“Pandas 提供了豐富的 IO 操作功能,支持從 CSV、SQL、Parquet 等多種文件格式中讀取數據。通過優化參數如 chunksize、usecols 和 dtype,可以顯著提升讀取速度并減少內存占用。”
1. 數據預處理類
在 Pandas 中,DataFrame 的數據預處理是數據分析的關鍵步驟,包括數據清洗、缺失值處理、縮尾處理、去重等操作。fillna、clip、winsorize 和 dropna 是數據預處理中常用的函數,用于處理缺失值、極端值以及修剪數據范圍。以下是它們的詳細介紹和用法:
1.1. fillna:填充缺失值
fillna 用于填充 DataFrame 或 Series 中的缺失值(NaN)。它支持多種填充方式,例如用固定值、前向填充、后向填充、均值填充等。
語法:
DataFrame.fillna(value=None, method=None, axis=None, inplace=False,
limit=None, downcast=None)
參數說明:
- ?value:用于填充缺失值的值,可以是標量、字典、Series 或 DataFrame。
- ?method:填充方法,可選 'ffill'(前向填充)、'bfill'(后向填充)。
- ?axis:填充的軸,0 表示按行填充,1 表示按列填充。
- ?inplace:是否原地修改數據,默認為 False。
- ?limit:限制填充的最大連續缺失值數量。
示例:
import pandas as pd
import numpy as np
# 創建示例 DataFrame
data = {'A': [1, 2, np.nan], 'B': [np.nan, 5, 6]}
df = pd.DataFrame(data)
# 用 0 填充缺失值
df_filled = df.fillna(0)
# 前向填充
df_ffill = df.fillna(method='ffill')
# 用均值填充
df_mean_filled = df.fillna(df.mean())
1.2. ?clip:修剪數據范圍
clip 用于將數據限制在指定的范圍內,超出范圍的值會被替換為邊界值。
DataFrame.clip(lower=None, upper=None, axis=None, inplace=False)
參數說明:
- lower:下限值,低于此值的會被替換為下限。
- ?upper:上限值,高于此值的會被替換為上限。
- axis:修剪的軸,0 表示按行修剪,1 表示按列修剪。
- ?inplace:是否原地修改數據。
示例:
# 將數據限制在 1 到 5 之間
df_clipped = df.clip(lower=1, upper=5)
# 對每列設置不同的上下限
lower = pd.Series([1, 2])
upper = pd.Series([4, 5])
df_clipped_custom = df.clip(lower=lower, upper=upper, axis=1)
1.3. ?winsorize:縮尾處理
winsorize 用于處理極端值,將超出指定分位數的值替換為分位數的值。它通常用于減少極端值對數據分析的影響。語法(通過 scipy.stats.mstats.winsorize):
from scipy.stats.mstats import winsorize
winsorize(data, limits=[lower_limit, upper_limit])
參數說明:
- ?limits:指定上下分位數,例如 [0.05, 0.95] 表示將低于 5% 和高于 95% 的值替換為對應分位數的值。
示例:
from scipy.stats.mstats import winsorize
# 對數據進行上下 5% 的縮尾處理
df['A_winsorized'] = winsorize(df['A'], limits=[0.05, 0.95])
1.4. ?dropna:刪除缺失值
dropna 用于刪除包含缺失值的行或列。
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
參數說明:
- axis:刪除的軸,0 表示刪除行,1 表示刪除列。
- ?how:刪除條件,'any'(默認)表示只要有一個缺失值就刪除,'all' 表示只有全部為缺失值才刪除。
- ?thresh:保留非缺失值的最小數量。
- ?subset:指定檢查缺失值的列。
- ?inplace:是否原地修改數據。
示例:
# 刪除包含缺失值的行
df_dropped = df.dropna()
# 刪除包含缺失值的列
df_dropped_cols = df.dropna(axis=1)
# 只刪除指定列中包含缺失值的行
df_dropped_subset = df.dropna(subset=['A'])
!!! 總結
- ?fillna:用于填充缺失值,支持多種填充方式。
- clip:用于將數據限制在指定范圍內,處理極端值。
- winsorize:用于縮尾處理,減少極端值的影響。
- dropna:用于刪除包含缺失值的行或列。
2. IO 操作
Pandas 中的 DataFrame 提供了豐富的 IO 操作功能,支持從多種文件格式中讀取數據,并將數據寫入到不同的文件格式中。
2.1. csv
2.1.1. 讀取 csv
CSV 是最常用的文件格式之一,Pandas 提供了 read_csv 函數來讀取 CSV 文件。
import pandas as pd
df = pd.read_csv('data.csv')
常用參數:
- sep:指定分隔符,默認為逗號 ,。
- header:指定標題行,默認為 0(第一行)。
- index_col:指定哪一列作為索引。
- encoding:指定文件編碼,如 utf-8 或 gbk。
- na_values:指定哪些值應被視為缺失值。
示例:
df = pd.read_csv('data.csv', sep=';', header=0, index_col='ID', encoding='utf-8')
2.1.2. 讀取 csv 時如何加速
在讀取大型 CSV 文件時,除了基本的 pd.read_csv 操作外,可以通過以下方法顯著提升讀取速度:
[分塊讀取 (chunksize)]
對于非常大的文件,一次性加載到內存可能會導致內存不足。可以使用 chunksize 參數分塊讀取數據,逐塊處理。
chunk_size = 10000 # 每次讀取 10000 行
for chunk in pd.read_csv('large_file.csv', chunksize=chunk_size):
process(chunk) # 自定義處理函數
這種方法可以有效減少內存占用,并允許邊讀邊處理。
[指定列讀取 (usecols)]
如果只需要部分列的數據,可以使用 usecols 參數指定要讀取的列,避免加載不必要的數據。
df = pd.read_csv('large_file.csv', usecols=['column1', 'column2'])
這樣可以減少內存使用并加快讀取速度。
[優化數據類型 (dtype)]
Pandas 默認會推斷每列的數據類型,但這可能會導致內存浪費。通過顯式指定 dtype,可以減少內存占用并提升性能。
dtypes = {'column1': 'int32', 'column2': 'float32'}
df = pd.read_csv('large_file.csv', dtype=dtypes)
例如,將 int64 改為 int32 可以節省內存。
[使用更高效的解析器 (engine='pyarrow')]
Pandas 1.4 版本引入了 pyarrow 作為 CSV 解析器,相比默認的解析器,速度更快。
df = pd.read_csv('large_file.csv', engine='pyarrow')
pyarrow 支持并行解析,特別適合處理大文件。
[?跳過無用數據 (skiprows, nrows)]
如果文件中有不需要的行或數據,可以使用 skiprows 跳過指定行,或使用 nrows 只讀取前幾行。
df = pd.read_csv('large_file.csv', skiprows=[1, 2], nrows=1000)
這樣可以減少數據處理量。
[?并行處理 (Dask 或 Multiprocessing)]
對于非常大的數據集,可以使用并行處理工具如 Dask 來加速讀取和處理。
import dask.dataframe as dd
df = dd.read_csv('large_file.csv')
result = df.groupby('column1').mean().compute()
Dask 會自動將文件分塊并并行處理。
[?使用更高效的文件格式 (如 Parquet)]
如果可能,將 CSV 文件轉換為 Parquet 格式,Parquet 是一種列式存儲格式,讀取速度更快。
df = pd.read_parquet('large_file.parquet', engine='fastparquet')
Parquet 文件不僅讀取速度快,還能顯著減少存儲空間。
[?內存映射文件 (memory_map)]
對于特別大的文件,可以使用 memory_map 參數將文件映射到內存中,減少內存占用。
df = pd.read_csv('large_file.csv', memory_map=True)
這種方法適合處理超大型文件。
2.1.3. 寫入 csv
使用 to_csv 函數將數據寫入 CSV 文件。
df.to_csv('output.csv', index=False)
常用參數:
- index:是否寫入索引,默認為 True。
- header:是否寫入列名,默認為 True。
- encoding:指定文件編碼。
2.2. pkl 和 hdf5
在 Pandas 中,DataFrame 可以方便地對 .pkl 和 .hdf5 文件進行讀寫操作。以下是詳細的方法和示例:
?
.pkl 文件是 Python 的序列化文件格式,通常用于保存和加載 Python 對象,包括 DataFrame。使用 read_pickle 方法從 .pkl 文件中加載 DataFrame,使用 to_pickle 方法將 DataFrame 保存為 .pkl 文件。
import pandas as pd
# 創建示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
# 保存為 .pkl 文件
df.to_pickle('data.pkl')
# 從 .pkl 文件加載 DataFrame
df = pd.read_pickle('data.pkl')
print(df)
.hdf5 是一種高效的存儲格式,適合存儲大規模數據。Pandas 提供了 HDFStore 和 to_hdf/read_hdf 方法來操作 .hdf5 文件。
# 保存為 .hdf5 文件
df.to_hdf('data.h5', key='df', mode='w')
# 從 .hdf5 文件加載 DataFrame
df = pd.read_hdf('data.h5', key='df')
print(df)
HDFStore 提供了更靈活的操作方式,支持多個數據集的存儲和讀取:
# 創建 HDFStore 對象
store = pd.HDFStore('data.h5')
# 存儲多個 DataFrame
store.put('df1', df1)
store.put('df2', df2)
# 讀取特定 DataFrame
df1 = store['df1']
df2 = store.get('df2')
# 關閉 HDFStore
store.close()
!!! Notes
總結:
- .pkl 文件:適合保存和加載單個 DataFrame,操作簡單。
- .hdf5 文件:適合存儲大規模數據,支持多個數據集和高效壓縮。
2.3. parquet
Pandas 支持讀取 Parquet 文件,使用 read_parquet 函數。
import pandas as pd
df = pd.read_parquet('data.parquet')
常用參數:
- engine:指定引擎,如 pyarrow 或 fastparquet。
- columns:指定要讀取的列。
示例:
df = pd.read_parquet('data.parquet', engine='pyarrow', columns=['col1', 'col2'])
2.4. html 和 md
Pandas 的 read_html 函數可以從網頁中讀取 HTML 表格數據。
url = 'http://example.com/table.html'
tables = pd.read_html(url)
df = tables[0] # 獲取第一個表格
如果需要處理復雜的網頁數據,可以結合 requests 和 BeautifulSoup 庫:
import requests
from bs4 import BeautifulSoup
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
table = soup.find_all('table')[0]
df = pd.read_html(str(table))[0]
2.5. sql
Pandas 支持從 SQL 數據庫中讀取數據,使用 read_sql 函數。
import sqlite3
# 連接到數據庫
conn = sqlite3.connect('database.db')
# 執行 SQL 查詢并讀取數據
df = pd.read_sql('SELECT * FROM table_name', conn)
# 關閉數據庫連接
conn.close()
如果需要連接其他數據庫(如 MySQL、PostgreSQL),可以使用相應的數據庫驅動(如 pymysql、psycopg2)。
浙公網安備 33010602011771號