数据清洗的核心步骤与基础方法
第一步:评估与诊断
在动手清洗前,先全面了解数据的状况。

- 查看数据概览:
- 检查数据问题:
第二步:处理缺失值
根据缺失原因、比例和业务逻辑选择策略。 | 方法 | 说明 | 适用场景 | | :--- | :--- | :--- | | 删除 | 删除缺失值所在的行或列。 | 缺失比例很高(如>50%),或缺失行对分析不重要。慎用,易损失信息。 | | 填充 | 用特定值替换。 | 缺失比例较低,且需要保留所有数据。 | | | 固定值填充:用0、‘Unknown’、中位数、众数等。 | 简单快捷,适用于数值或分类。 | | | 前向/后向填充:用前一个或后一个有效值填充。 | 时间序列数据。 | | | 统计量填充:用均值、中位数(数值)、众数(分类)填充。 | 数据分布较均匀时。 | | | 插值法:线性、多项式插值。 | 有序数据(如时间序列)。 | | | * 模型预测填充:用其他列建立模型预测缺失值。 | 数据量大,关系复杂时。 | | 保留 | 将缺失视为一种特殊状态。 | 缺失本身可能有意义(如“用户未填写收入”)。 |
第三步:处理异常值
异常值可能是错误,也可能是重要信息(如欺诈交易)。
- 检测方法:
- 处理方法:
第四步:处理不一致与格式化
- 文本数据:
- 大小写统一:
df[‘col’] = df[‘col’].str.lower() - 去除空格:
df[‘col’] = df[‘col’].str.strip() - 统一格式:如日期格式
pd.to_datetime(df[‘date’], format=‘%Y/%m/%d’) - 映射替换:
df[‘gender’].replace({‘M’:‘male’, ‘F’:‘female’}) - 正则表达式:提取、替换复杂模式的文本。
- 大小写统一:
- 分类数据:
- 合并同类项:将含义相同但表述不同的值合并。
第五步:处理重复值
- 完全重复:
df.drop_duplicates(inplace=True) - 关键字段重复:根据业务逻辑,判断哪些列组合应唯一(如用户ID+下单时间),然后删除重复。
- 判断保留哪条:可能需要根据时间戳或其他列排序后保留最新/最旧的一条。
第六步:类型转换与衍生
- 数据类型转换:
- 将数字存储为字符串的列转为数值型:
pd.to_numeric(df[‘col’], errors=‘coerce’) - 将分类文本转为
category类型以节省内存。 - 将布尔值转换为
0/1。
- 将数字存储为字符串的列转为数值型:
- 创建衍生特征:
- 从日期中提取年、月、季度、星期几。
- 将连续值分箱(如年龄分为“青年”、“中年”、“老年”)。
- 组合多个特征(如“面积”/“人口”得到“人口密度”)。
第七步:验证与保存
- 验证清洗效果:
- 再次运行
df.info(),df.describe(),检查缺失、类型、统计量。 - 进行业务逻辑检查(如年龄不应为负,销售额与单价*数量应一致)。
- 再次运行
- 保存清洗后数据:
- 保存为新文件,永远保留原始数据备份。
常用工具与代码示例(Python Pandas)
import pandas as pd import NumPy as np df = pd.read_csv(‘dirty_data.csv’) # 2. 诊断 print(df.info()) print(df.isnull().sum()) # 3. 处理缺失值 - 填充 df[‘income’].fillna(df[‘income’].median(), inplace=True) # 中位数填充 df[‘education’].fillna(‘Unknown’, inplace=True) # 固定值填充 # 4. 处理异常值 - 截断 (箱线图法) Q1 = df[‘salary’].quantile(0.25) Q3 = df[‘salary’].quantile(0.75) IQR = Q3 - Q1 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR df[‘salary’] = df[‘salary’].clip(lower_bound, upper_bound) # 将超出部分截断到边界 # 5. 处理不一致性 df[‘city’] = df[‘city’].str.strip().str.title() # 去除空格并首字母大写 df[‘gender’] = df[‘gender’].replace({‘M’:‘Male’, ‘F’:‘Female’, ‘m’:‘Male’}) # 6. 处理重复值 df.drop_duplicates(subset=[‘user_id’, ‘order_time’], keep=‘last’, inplace=True) # 7. 类型转换 df[‘signup_date’] = pd.to_datetime(df[‘signup_date’]) df[‘age’] = pd.to_numeric(df[‘age’], errors=‘coerce’) # 8. 衍生特征 df[‘signup_year’] = df[‘signup_date’].dt.year df[‘age_group’] = pd.cut(df[‘age’], bins=[0, 18, 35, 60, 100], labels=[‘少年’, ‘青年’, ‘中年’, ‘老年’]) # 9. 保存 df.to_csv(‘cleaned_data.csv’, index=False)
核心原则与建议
- 先备份,再操作:永远保留一份原始数据的副本。
- 记录清洗步骤:创建数据清洗日志或脚本,确保过程可复现、可审计。
- 理解业务逻辑:很多清洗决策(如如何处理异常值)需要结合领域知识,不能仅依赖统计方法。
- 迭代进行:数据清洗不是一步到位的线性过程,常常需要“诊断-处理-再诊断”的循环。
- 平衡效率与质量:对于大型数据集,有时需要在完美清洗和计算效率之间做出权衡。
掌握这些基础方法后,您就能应对80%以上的常见数据清洗任务,更复杂的情况(如文本清洗、非结构化数据清洗)则需要在基础上深入学习特定技术。