Python数据清洗实战:缺失数据与异常值处理全攻略
在数据分析和机器学习的工作流中,数据清洗是绕不开的关键环节。粗糙的数据就像未打磨的原石,即便算法再精妙,也难以提炼出有价值的信息。其中,缺失数据与异常值是最常见的两类问题,它们不仅会干扰统计分析结果,还可能导致模型训练出现偏差。本文将结合Python实战,系统讲解这两类问题的处理方法。
一、缺失数据:看不见的“数据黑洞”
缺失数据指的是数据集中存在的空白或无效值,通常以NaN(Not a Number)或None的形式出现。它们可能源于数据采集时的遗漏、存储错误或者用户未填写等原因。
1. 缺失数据的识别
在Python中,我们可以借助pandas库快速定位缺失值:
Python
复制
import pandas as pd import numpy as np # 创建含缺失值的示例数据集 data = pd.DataFrame({ 'A': [1, 2, np.nan, 4], 'B': [5, np.nan, np.nan, 8], 'C': [9, 10, 11, 12] }) # 查看每个特征的缺失值数量 print(data.isnull().sum()) # 查看数据集整体缺失情况 print(data.isnull().mean() * 100) # 以百分比显示
2. 缺失数据的处理策略
处理缺失值没有绝对最优的方法,需结合业务场景和数据分布选择合适的方案:
-
删除法:适用于缺失比例极低(如<5%)或缺失值随机分布的情况
Python
复制
# 删除含缺失值的行 data_drop_row = data.dropna(axis=0) # 删除含缺失值的列 data_drop_col = data.dropna(axis=1) -
填充法:最常用的处理方式,分为简单填充和智能填充
Python
复制
# 均值填充(适用于正态分布的数值型数据) data_fill_mean = data.fillna(data.mean()) # 中位数填充(适用于存在异常值的数值型数据) data_fill_median = data.fillna(data.median()) # 众数填充(适用于分类数据) data_fill_mode = data.fillna(data.mode().iloc[0]) # 前向填充/后向填充(适用于时间序列数据) data_fill_ffill = data.fillna(method='ffill') # 前向填充 data_fill_bfill = data.fillna(method='bfill') # 后向填充 -
模型预测法:对于缺失比例较高的特征,可以用其他特征构建模型预测缺失值
Python
复制
from sklearn.ensemble import RandomForestRegressor # 分离含缺失值的特征和其他特征 data_train = data[data['A'].notnull()] data_test = data[data['A'].isnull()] # 训练模型 model = RandomForestRegressor() model.fit(data_train[['B', 'C']], data_train['A']) # 预测缺失值 data.loc[data['A'].isnull(), 'A'] = model.predict(data_test[['B', 'C']])
二、异常值:数据中的“离群者”
异常值是指与其他数据点显著偏离的值,可能是真实的极端情况,也可能是数据录入错误。异常值会严重影响统计分析的结果,比如拉高均值、扩大方差。
1. 异常值的识别
常用的异常值检测方法包括:
-
统计分析法:基于正态分布的3σ原则,超出均值±3倍标准差的值视为异常值
Python
复制
# 计算均值和标准差 mean = data['A'].mean() std = data['A'].std() # 识别异常值 outliers = data[(data['A'] < mean - 3*std) | (data['A'] > mean + 3*std)] -
四分位数法(IQR):不受分布假设影响,更适合非正态分布数据
Python
复制
# 计算四分位数和四分位距 q1 = data['A'].quantile(0.25) q3 = data['A'].quantile(0.75) iqr = q3 - q1 # 识别异常值 outliers = data[(data['A'] < q1 - 1.5*iqr) | (data['A'] > q3 + 1.5*iqr)] -
可视化法:通过箱线图、散点图直观识别异常值
Python
复制
import matplotlib.pyplot as plt # 绘制箱线图 plt.boxplot(data['A']) plt.title('Boxplot of Feature A') plt.show()
2. 异常值的处理策略
处理异常值需先判断其产生原因,再选择对应策略:
-
删除法:适用于异常值为数据录入错误的情况
Python
复制
# 删除异常值所在行 data_clean = data[(data['A'] >= q1 - 1.5*iqr) & (data['A'] <= q3 + 1.5*iqr)] -
修正法:若异常值为真实数据但超出合理范围,可以进行截断处理
Python
复制
# 截断异常值到合理范围 data['A'] = np.where(data['A'] > q3 + 1.5*iqr, q3 + 1.5*iqr, data['A']) data['A'] = np.where(data['A'] < q1 - 1.5*iqr, q1 - 1.5*iqr, data['A']) -
分箱法:将数值型数据划分为不同区间,弱化异常值的影响
Python
复制
# 等频分箱 data['A_bin'] = pd.qcut(data['A'], q=4, labels=['Q1', 'Q2', 'Q3', 'Q4']) -
保留法:若异常值代表真实的极端情况(如用户消费峰值),可以保留并在建模时使用对异常值不敏感的算法(如决策树、随机森林)
三、数据清洗的最佳实践
- 先分析后处理:在处理缺失值和异常值前,务必先分析其产生原因和分布特征,避免盲目操作
- 记录清洗过程:详细记录每一步清洗操作,保证数据处理的可追溯性
- 验证清洗效果:清洗完成后,通过统计指标和可视化方法验证数据质量是否提升
- 结合业务场景:所有处理方法都应服务于业务目标,避免为了清洗而清洗
金句:数据清洗的本质不是消除所有“不完美”,而是让数据更贴合业务需求,为后续分析和建模提供可靠基础。
更多推荐



所有评论(0)