Pandas缺失值处理(Missing Data)完全指南
1. 什么是缺失值(Missing Data)
在数据分析中,缺失值是指数据集中某些观测值或变量缺少数据值的情况。Pandas中主要有两种表示缺失值的方式:
NaN
(Not a Number): 用于浮点数据类型NA
(Not Available): 用于其他数据类型
import numpy as np
import pandas as pd
# 创建包含缺失值的DataFrame
df = pd.DataFrame({
'A': [1, 2, np.nan, 4],
'B': [5, np.nan, np.nan, 8],
'C': ['a', 'b', 'c', np.nan]
})
print(df)
输出:
A B C
0 1.0 5.0 a
1 2.0 NaN b
2 NaN NaN c
3 4.0 8.0 NaN
解释:
- 我们创建了一个包含三列的DataFrame
- 列A和B是数值型,使用
np.nan
表示缺失值 - 列C是字符串类型,Pandas会自动将None或np.nan转换为NA
2. 检测缺失值
Pandas提供了多种方法来检测缺失值:
2.1 使用isna()或isnull()
# 检测缺失值
print(df.isna())
输出:
A B C
0 False False False
1 False True False
2 True True False
3 False False True
2.2 检测每列的缺失值数量
# 统计每列缺失值数量
print(df.isna().sum())
输出:
A 1
B 2
C 1
dtype: int64
2.3 检测每行的缺失值数量
# 统计每行缺失值数量
print(df.isna().sum(axis=1))
输出:
0 0
1 1
2 2
3 1
dtype: int64
3. 删除缺失值
3.1 删除包含缺失值的行
# 删除包含任何缺失值的行
df_dropped = df.dropna()
print(df_dropped)
输出:
A B C
0 1.0 5.0 a
3.2 删除包含缺失值的列
# 删除包含任何缺失值的列
df_dropped_col = df.dropna(axis=1)
print(df_dropped_col)
输出:
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3]
3.3 设置阈值删除
# 只保留至少有2个非NA值的行
df_thresh = df.dropna(thresh=2)
print(df_thresh)
输出:
A B C
0 1.0 5.0 a
1 2.0 NaN b
3 4.0 8.0 NaN
4. 填充缺失值
4.1 用固定值填充
# 用0填充所有缺失值
df_filled = df.fillna(0)
print(df_filled)
输出:
A B C
0 1.0 5.0 a
1 2.0 0.0 b
2 0.0 0.0 c
3 4.0 8.0 0
4.2 向前填充(ffill)
# 用前一个值填充缺失值
df_ffill = df.fillna(method='ffill')
print(df_ffill)
输出:
A B C
0 1.0 5.0 a
1 2.0 5.0 b
2 2.0 5.0 c
3 4.0 8.0 c
4.3 向后填充(bfill)
# 用后一个值填充缺失值
df_bfill = df.fillna(method='bfill')
print(df_bfill)
输出:
A B C
0 1.0 5.0 a
1 2.0 8.0 b
2 4.0 8.0 c
3 4.0 8.0 NaN
4.4 用统计值填充
# 用列的平均值填充数值列
df_mean = df.copy()
df_mean['A'] = df_mean['A'].fillna(df_mean['A'].mean())
df_mean['B'] = df_mean['B'].fillna(df_mean['B'].median())
# 用众数填充字符串列
mode_C = df_mean['C'].mode()[0]
df_mean['C'] = df_mean['C'].fillna(mode_C)
print(df_mean)
输出:
A B C
0 1.0 5.0 a
1 2.0 6.5 b
2 2.333333 6.5 c
3 4.0 8.0 a
5. 插值法处理缺失值
Pandas提供了插值方法,可以更智能地填充缺失值:
# 创建一个时间序列数据
ts = pd.Series([1, np.nan, np.nan, 8, 10, np.nan, 15])
# 线性插值
linear_interp = ts.interpolate()
print("线性插值:\n", linear_interp)
# 时间插值
time_interp = ts.interpolate(method='time')
print("\n时间插值:\n", time_interp)
# 多项式插值
poly_interp = ts.interpolate(method='polynomial', order=2)
print("\n多项式插值:\n", poly_interp)
6. 高级缺失值处理技巧
6.1 使用where和mask
# 替换满足条件的值为NA
df_masked = df.where(df > 2)
print(df_masked)
6.2 使用replace
# 将特定值替换为NA
df_replace = df.replace('a', np.nan)
print(df_replace)
6.3 使用插值限制
# 限制插值的连续缺失值数量
ts = pd.Series([1, np.nan, np.nan, np.nan, np.nan, 6])
limited_interp = ts.interpolate(limit=2)
print(limited_interp)
7. 总结
处理缺失值是数据清洗的重要环节,Pandas提供了丰富的工具:
- 检测缺失值:使用
isna()
或isnull()
方法可以轻松识别数据中的缺失值 - 删除缺失值:
dropna()
方法提供了灵活的删除选项,可以按行或列删除 - 填充缺失值:
fillna()
方法支持多种填充策略,包括固定值、前向/后向填充、统计值填充等 - 插值方法:
interpolate()
提供了更智能的填充方式,如线性插值、多项式插值等
选择哪种方法取决于具体的数据场景和分析需求。一般来说:
- 当缺失值很少时,可以直接删除
- 当数据有明确趋势时,插值法是更好的选择
- 对于分类数据,使用众数或固定值填充可能更合适
正确处理缺失值能够提高数据分析的准确性和可靠性,是数据预处理中不可忽视的重要步骤。