数据清洗第一课:缺失值、重复值和异常值怎么处理

📅 2026/7/6 13:31:02
数据清洗第一课:缺失值、重复值和异常值怎么处理
模型效果不好第一反应常常是换个更高级的算法。但真实项目里更常见的原因是数据本身就有问题缺失没处理、重复没去、异常值没排查。这一课不写复杂模型把数据清洗里最常见的三类问题讲清楚缺失值、重复值和异常值。你的浏览器暂不支持视频播放可以继续阅读下方文字版课程。第 22 课视频 · 数据清洗第一课约 1 分 40 秒数据清洗到底在清什么数据清洗不是为了让表格看起来整齐而是要解决一个核心问题模型拿到的数据能不能代表真实世界能不能稳定计算会不会误导训练。常见脏数据有五类类型表现对模型的影响缺失值某些字段没有记录算不动或填充方式不对会引入偏差重复值同一条样本出现多次模型对这类样本过度重视异常值数值明显偏离合理范围拉偏均值、扭曲拟合方向格式混乱日期、金额、类别写法不统一同义值被当成不同类别标签错误答案本身标错了模型认真学习错误答案这一课聚焦前三类它们最常见处理不好直接毁掉模型。缺失值先判断含义再决定删或填缺失值就是数据里没有记录的部分。先看一个用户表年龄 收入 是否购买 25 8000 是 空 12000 否 38 空 是看到空值先别急着dropna()全删。要先问两个问题这个字段对预测重要吗不重要的字段直接删列可能比硬填一个值更好。缺失本身有没有业务含义有的话应该额外标记而不是抹掉。空值有时候本身就是信号。比如用户没填收入可能对隐私特别敏感某种医疗检测没做可能因为患者看起来就很健康。没做检测本身就是一条信息删掉就丢了。三种处理方式删、填、加标记先建一份带缺失值的模拟数据后面所有清洗操作都基于它importpandasaspdimportnumpyasnp# 模拟一份真实脏数据缺失、重复、异常都混在一起dfpd.DataFrame({user_id:[101,102,103,104,105,101,106,107],age:[25,np.nan,38,300,45,25,52,33],# 300 是录入错误income:[8000,12000,np.nan,9500,-5000,8000,60000,7200],# -5000 错误60000 偏高city:[北京,上海,广州,深圳,杭州,北京,np.nan,成都],is_buy:[是,否,是,是,否,是,是,否],})# 第 6 行index 5和第 1 行index 0完全重复方式一删除。缺失比例极低、且缺失样本没有特殊性时可以删# 缺失比例极低、且缺失样本没有特殊性时才删否则会丢掉有用样本dfdf.dropna()方式二填充。数值字段用中位数比均值更抗异常值类别字段补一个未知类别# 中位数比均值更抗异常值避免被极端值拉偏df[age]df[age].fillna(df[age].median())# 类别字段补未知而不是用众数硬填一个虚假的常见值df[city]df[city].fillna(未知)方式三加缺失标记。如果缺失本身可能有意义额外加一列让模型既看到填充后的数值也知道这条记录原本是缺失的# 缺失本身是信号用单独一列把它留住再填数值列df[income_missing]df[income].isna().astype(int)df[income]df[income].fillna(df[income].median())重复值结合业务主键判断同一条记录出现多次模型会以为这类样本更重要。比如同一个用户的行为记录出现 3 次模型就会把这条样本的权重学到 3 倍。检查并删除完全重复的行# 先看有多少完全重复的行再决定是否删print(df.duplicated().sum())dfdf.drop_duplicates()但不是所有相似的记录都该删。同一个user_id出现多次可能是数据重复也可能是同一用户在不同时间下了多笔订单那是真实行为不能去重。判断重复要结合业务主键# 按 user_id order_id 判断是否真正重复# 同一用户不同时间的多笔订单不会被误删df.duplicated(subset[user_id,order_id]).sum()异常值统计方法定位业务知识决策异常值是明显偏离大多数样本的值。先看几个例子值判断可能处理年龄 300不可能录入错误标为缺失或删除月收入 -5000不可能数据错误标为缺失或删除身高 5 米不可能单位错误可能是英尺按规则修正或标缺失单笔消费 50 万可能大客户结合业务上下文决定先用统计方法定位可疑值IQR四分位距最常用# IQR 法定位可疑值只能定位不能替你决策q1df[income].quantile(0.25)q3df[income].quantile(0.75)iqrq3-q1 lowerq1-1.5*iqr upperq31.5*iqr suspiciousdf[(df[income]lower)|(df[income]upper)]print(f可疑样本数:{len(suspicious)})IQR 只能帮你定位不能帮你决策。一个数是录入错误还是真实大客户统计方法回答不了得靠业务知识。四种处理策略修正、删除、截断、保留修正明显是单位或录入错误的按规则修正比如把 5 米身高换算回英尺。删除确认是错误记录、且样本量充足时可以删。截断把极端值压到合理范围避免少数极端值污染整列# 把收入压到 0-100000过大的值不再直接拉偏模型df[income]df[income].clip(lower0,upper100000)保留真实业务现象比如大客户、高消费用户删了反而丢掉重要信息。清洗时最容易踩的三个坑坑一先填充再拆分数据集用全量数据算均值再分训练集和测试集会造成数据泄漏data leakage测试集的信息漏进了训练阶段的统计量上线后评估会偏乐观。正确做法是先拆分只在训练集上学习填充规则再应用到测试集fromsklearn.model_selectionimporttrain_test_split# 先拆分避免测试集信息泄漏到训练集的统计量里train_df,test_dftrain_test_split(df,test_size0.2,random_state42)# 只用训练集算填充值再套用到测试集median_incometrain_df[income].median()train_df[income]train_df[income].fillna(median_income)test_df[income]test_df[income].fillna(median_income)坑二过度清洗为了追求干净把不顺眼的样本全删了训练集会过于理想化模型上线后水土不服。真实世界的数据本来就是脏的模型得见过脏数据才能适应。坑三只洗特征不查标签标签本身错了模型就会非常认真地学习错误答案。检查标签分布、抽样核对标签都是清洗的一部分不能只盯着特征列。小结缺失值先判断缺失是否有含义再决定删、填还是加标记。重复值结合业务主键判断不能机械去重。异常值统计方法定位业务知识决策不能一刀切。黄金法则只在训练集上学习清洗规则再应用到验证集和测试集。下一课用 Pandas 做一次小型清洗实战把混乱表格一步步整理成可以训练的数据。思考题一个字段缺失率高达 80%你会直接删列还是先看缺失和非缺失样本在其他维度上有没有系统性差异一个数值特征 99% 的数据落在 0 到 1000但有 1% 落在 10000 到 50000。你会怎么判断这些是异常值还是重要的大客户你有没有遇到过标签本身就是错的的项目你是怎么发现的在线阅读点击这里阅读博客原文原文地址https://bestsdz.xyz/posts/data-cleaning-first-lesson/