做数据分析的人基本都有同感:拿到手的数据,十有八九是不干净的。尤其是从Excel、业务系统或者爬虫接口里导出来的表,缺失值、异常值、重复值往往同时扎堆出现,这时候Python数据分析的三板斧就派上用场了——NumPy负责底层数值计算,Pandas负责表格级处理,而数据清洗就是其中最磨人、也最出成果的一步。
在系列的前两讲里,我们已经把NumPy数组操作和Pandas的DataFrame/Series基础过了一遍。这一讲专门讲数据清洗:缺失值怎么填、异常值怎么查、重复值怎么去,以及类型转换、文本清洗这些经常被忽略的细节。不管你是刚入门还在啃文档,还是已经在用Pandas处理日常报表,这篇文章都值得花十分钟看完。很多公司在数据分析笔试面试里,数据清洗都是必考项,原因很简单——真实业务里的数据,永远不会像教程里那么干净。
1. 为什么数据清洗值得单独开一讲
1.1 数据清洗在数据分析流程中的角色
很多人学数据分析,一上来就盯着建模、可视化,觉得那才是“高光时刻”。但实际工作中,数据清洗往往占到整个项目40%到80%的时间。不是夸张,你去问任何一个数据工程师或者数据分析师,他都会告诉你:报表延迟、结果对不上、模型效果差,八成问题出在数据质量上。
数据清洗在整条链路里的位置,正好是“数据获取”和“分析建模”之间的缓冲带。数据从数据库、Excel、CSV、API接口进来之后,不会直接变成能用的DataFrame——里面可能有空单元格、有文本里混着的数字、有改了格式的日期,还有重复录入的行。这些都要在进入分析之前处理掉,否则后面做的透视表、趋势图、机器学习模型,全是建立在沙子上。
1.2 数据问题从哪里来
数据脏不是偶然的,它有固定的来源。我梳理了几类最常见的场景:
- 业务系统导出:ERP、CRM这类系统导出的数据,经常有空值表示“未填写”,比如客户没有填性别、订单备注为空。
- 多表拼接产生:用merge或者Excel的VLOOKUP拼接数据时,匹配不上的字段会产生NaN。
- 人为录入错误:手输的表格里,手机号可能多一位、日期可能写成“2024/1/1”和“2024-01-01”两种格式共存。
- 爬虫采集:网页上有些字段缺失,爬下来就是空值,或者带了多余的空格和HTML标签。
- 系统Bug或埋点缺失:埋点统计漏掉了某些用户行为,这种缺失往往是大面积的。
这些问题的共同点是:你没法靠肉眼去逐行排查,必须用系统性的方法去发现和处理。这也是Pandas擅长的地方。
1.3 清洗的整体思路:先定位、再评估、后处理
我的习惯是固定走四步:定位、评估、处理、验证。不要一上来就调用dropna()或者fillna(),先搞清楚数据到底哪里出了问题。
- 定位:用df.info()、df.isnull().sum()、df.duplicated().sum()这些方法,把缺失、重复、类型异常都摸清楚。
- 评估:每一项数据问题影响多大?是5%的缺失还是50%的缺失?是整列都异常还是只有几行?
- 处理:针对不同情况选择删除、填充、转换或者保留。
- 验证:处理完之后,再跑一遍检查代码,确认问题被解决,同时确认没有引入新的问题。
这套流程看起来简单,但能帮你避免很多“修好了这个,又搞坏了那个”的尴尬。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 缺失值处理:先看清坑在哪,再决定怎么填
2.1 缺失值的识别与统计
在Pandas里,缺失值默认用NaN(Not a Number)表示,它来自NumPy的float类型。一组数据里只要混入了NaN,这一列就会被自动推断成float,这也是新手最容易困惑的地方——为什么年龄明明是整数,打印出来却带小数点?
识别缺失值最常用的方法是isnull()和isna(),两者完全等价,看你习惯用哪个。配合sum()就能统计每一列的缺失数量:
python复制import pandas as pd
import numpy as np
df = pd.DataFrame({
"订单号": ["A001", "A002", "A003", "A004"],
"金额": [1200, np.nan, 800, 1500],
"用户ID": ["U01", "U02", np.nan, "U03"]
})
print(df.isnull().sum())
输出结果很直观:金额有1个缺失,用户ID有1个缺失。如果数据量大,这个方法比肉眼扫Excel高效太多了。
还有一个常用方法是info(),它会显示每一列的非空数量、数据类型和内存占用。数据量上百万时,还要注意用memory_usage()去看内存占用有没有超标。很多公司笔试里会问“如何高效检查大数据集的缺失值”,标准答案就是这两招。
2.2 删除还是填充:先回答三个问题
看到缺失值,不要条件反射地删除。删除意味着丢失信息,如果缺失比例很高,删完之后样本量不够,分析结果就没有统计意义了。我在处理之前会先问自己三个问题:
- 缺失比例是多少?低于5%可以考虑删除,超过20%就要慎重,通常选择填充或单独处理。
- 缺失是随机的吗?如果某个字段只在特定条件下缺失,比如“退单金额”只在退单记录里有值,那缺失本身就是一种业务信息,不能随便填。
- 这一列后续分析用得上吗?如果用不上,直接删掉整列更省事。
这三个问题问完,处理方向基本就清楚了。随机缺失且比例低,删行;非随机缺失,保留缺失标志或者填充;字段废了,删列。
删除操作用dropn
