# 删除任何含有缺失的行 df.dropna(inplace=True) # 删除缺失比例超过50%的列 df.dropna(thresh=len(df)*0.5, axis=1)
# 均值填充 df['age'].fillna(df['age'].mean()) # 线性插值 df['temperature'].interpolate(method='linear') # 前向填充 df['sales'].fillna(method='ffill')
df.duplicated() 返回布尔序列df.duplicated(subset=['col1','col2'])df[df.duplicated()]df.drop_duplicates() 保留第一次出现keep='last' 保留最后一次keep=False 删除所有重复# 删除完全重复的行 df.drop_duplicates(inplace=True) # 基于特定列去重 df.drop_duplicates(subset=['user_id'], keep='first')
| ID | 姓名 | 年龄 | 重复标记 |
|---|---|---|---|
| 101 | 小美 | 12 | ✅ 唯一 |
| 102 | 小智 | 13 | ⚠️ 重复 (第1次) |
| 102 | 小智 | 13 | ⚠️ 重复 (第2次) |
| 103 | 小刚 | 11 | ✅ 唯一 |
# IQR 截尾 Q1 = df['score'].quantile(0.25) Q3 = df['score'].quantile(0.75) IQR = Q3 - Q1 lower = Q1 - 1.5*IQR upper = Q3 + 1.5*IQR df['score'] = df['score'].clip(lower, upper)
# 等宽分箱 pd.cut(df['age'], bins=3, labels=['少年','青年','成年']) # 等频分箱 pd.qcut(df['income'], q=4, labels=['低','中低','中高','高'])
# 将异常值替换为中位数 median_val = df['price'].median() df.loc[df['price'] > 10000, 'price'] = median_val
| 问题类型 | 方法 | 适用场景 | 注意事项 |
|---|---|---|---|
| 缺失值 | 删除 | 缺失极少 <5% | 可能丢失信息 |
| 缺失值 | 均值/中位数填充 | 数值型,分布较对称 | 可能降低方差 |
| 缺失值 | 插值 | 时间序列,有序数据 | 计算成本略高 |
| 重复数据 | drop_duplicates | 完全重复或关键列重复 | 确认保留规则 |
| 异常值 | 截尾 (clip) | 极端值影响模型 | 边界需合理 |
| 异常值 | 分箱 | 将连续值离散化 | 可能损失精度 |
| 异常值 | 替换 | 少量明显错误 | 避免引入偏差 |