1.1 "脏数据"不是只有缺失值
我把这些年见过的高频脏数据问题整理成了一张表,遇到数据文件时直接对照着查:
| 问题类型 | 具体表现 | 常见来源 | 处理优先级 |
|---|---|---|---|
| 缺失值 | 某个字段大量为空或部分为空 | 用户不填、系统采集中断、多表关联丢失 | 高 |
| 异常值 | 数值明显超出业务合理区间 | 传感器故障、手工录入错误、极端真实事件 | 高 |
| 重复值 | 全行重复或关键字段重复 | 多次导入、数据源重复推送 | 高 |
| 格式混乱 | 日期格式不统一、编码不一致 | 多系统导出、跨地区数据源 | 高 |
| 量纲差异 | 销售额几万、折扣率零点几 | 原始业务字段直接拼接 | 中 |
| 语义不一致 | 性别写成男/M/1/男性 | 不同系统字典不同 | 中 |
| 无效字段 | 某一列几乎全是同一个值 | 常量列、未更新字段 | 低 |
大部分新人只盯着第一类"缺失值"处理,却忽略了其他更隐蔽的问题。我印象最深的一个项目里,某门店ID列在订单表里是字符串"1001",在门店表里是数字1001,合并时没有统一判断,直接导致关联后丢了两千多条记录,这种问题不仔细看根本发现不了。
1.2 数据预处理的边界:到什么程度算处理完
处理到什么时候可以停手?这是团队里经常争论的问题。我的判断标准是三个状态:
第一是合法,字段类型全部正确、值域在合理范围、类别取值统一。第二是一致,多表能够顺畅对齐,主键没有冲突。第三是可用,数据分布满足建模算法的最基本假设,类别变量已经编码,数值变量的量纲正常。
我习惯在开工前先跑一遍质量检查清单:文件读取是否报错?列名和 dtype 是否符合预期?还有没有空值?每个分类字段的取值集合是什么?数值字段的取值范围是否有意外?有没有全列都一样的常量列?有没有重复行?这七个问题全部过一遍,再决定下一步做什么。
做预处理最忌讳的就是埋头写代码,写了几百行清洗逻辑才发现源数据结构理解错了,返工成本极高。
2. 四步主线:清洗、集成、变换、规约,以及怎么画项目流程图
数据预处理有很多种框架,业界最常用的是R:《数据挖掘:概念与技术》中的四阶段模型,把它当成主线来规划项目结构,个人和团队协作都方便。
code复制原始数据 → 数据清洗 → 数据集成 → 数据变换 → 数据规约 → 建模就绪数据
但要强调一点,实际项目里这条链路绝对不是线性的。我做过一个零售分析项目,清洗完订单表之后发现门店表和订单表的关联字段格式对不上,只好退回集成阶段重新统一。所以真实的流程图应该是一个带反馈环的循环,每个阶段都可能会跳回前序阶段。画流程图时,我建议把"数据探查"放在最前面,因为清洗、集成、变换的方案全部依赖探查结果。
2.1 数据清洗是底线工程
清洗解决的是数据的"脏、缺、重、乱"四个问题。脏指字段取值不合理,缺指缺失值,重指重复记录,乱指格式不统一。在操作顺序上,我习惯先做格式统一,再做缺失值处理,最后处理异常值和重复值。理由很简单:有些格式问题(比如"TRUE"和"True")不统一,去重时会误判成不同的值;日期格式不统一时,按时间排序去重也会出错。
清洗环节最需要业务知识的介入。你不可能脱离业务单纯靠统计方法判断某个值是缺失、是异常、还是真实存在的极端情况,这一点在后面的异常值处理部分会详细展开。
2.2 数据集成:多表合并不是拼个 concat
常见误区是把"集成"等同于 pd.concat 或者 SQL 里把表拼在一起。实际要处理的问题多得多。
首先是主键字段名不一致,两张表里一个叫 ShopID 一个叫 shop_id。其次是字段编码不一致,同一家门店在一张表里叫 1001,在另一张表里叫 A1001。更复杂的是关系没有理清楚,连表之前没确认是一对一、一对多还是多对多,直接 left join 之后行数爆炸。
我的建议是正式合并前,先单独检查每张表主键的唯一性。再用小样本数据分别做一次 inner join 和 outer join,对比行数差异,能非常有效地暴露关联逻辑的问题。
2.3 数据变换:让不同量纲的数据"说同一种语言"
数据变换解决的是"算法能不能直接用"的问题,基础操作包括三个方向:
连续变量离散化。比如把年龄切成青年、中年、老年,或者把销售额按分位数分成高、中、低档。这个操作可以帮助模型捕捉非线性关系,但也容易丢失信息,要谨慎。
数值变换改变分布形态。比如对长尾数据做对数变换,这是处理偏态分布最常用的手段之一。
标准化与归一化。让不同量纲的数值特征处在一个可比的范围,具体方法后面单独讲。
还有一个必须放在这里的操作是类别变量编码。很多算法只能吃数值,吃不了"红""绿""蓝"这种字符串,得把类别转成数字。编码方式的选择直接影响特征维度、模型解释性和最终效果,这里面的学问也很大。
2.4 数据规约:不是非要用 PCA
数据规约的目的是在尽量保留信息的前提下减少数据规模,从而提升计算效率。方法大致分三类:维度规约(PCA、特征选择)、数量规约(抽样、重采样)、数值规约(用更少的状态表示数据)。
我最想提醒的是,别把 PCA 当标准动作。很多项目的特征本来就几十个,样本量也不大,训练时间根本不是瓶颈,强行降维唯一的作用是让模型损失一部分信息的可解释性。规约应该是在数据量大、计算慢、存储压力大的场景下才动用的一项可选操作。
数据规约的另一个实用手段是采样。类别极度不平衡时,下采样多数类或上采样少数类都是常规操作,这些也属于规约的范畴。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
3. 用 pandas 写一套可直接复用的清洗代码
前两部分讲概念,这部分直接进代码。以下代码基于 pandas 和 numpy,是我最常用的基础清洗模板,可以直接复制到项目里改字段名使用。
3.1 第一步永远是探查,不是清洗
python复制import pandas as pd
import numpy as np
# 读取数据,编码问题最常见
df = pd.read_csv('raw_data.csv', encoding='utf-8')
# 如果上面报错,试试 gbk/gb2312 编码
# df = pd.read
