缺失值处理(上):缺失值识别、统计与可视化

各位好,欢迎来到第三章。

上一章我们聊了数据清洗的准备工作,包括数据类型转换和重复值处理。今天咱们进入一个更核心的话题——缺失值。

说实话,我做了这么多年数据清洗,遇到最多的坑就是缺失值。你想想看,一个数据集里,如果某个字段空了一大片,你直接拿去做分析,结果基本就是废的。所以,处理缺失值之前,咱们得先搞清楚三件事:哪些地方有缺失?缺了多少?缺失的分布有没有规律?

3.1 缺失值识别:找到那些「空」

缺失值在Python里通常表现为NaN(Not a Number),或者None。但实际项目中,我见过更离谱的——有人把缺失值填成"NULL""N/A""未知",甚至直接填个0。嗯,这些都属于「伪缺失」,咱们后面会专门讲怎么处理。

先看最标准的识别方法:

import pandas as pd
import numpy as np

# 创建一个带缺失值的示例数据
df = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六'],
    '年龄': [25, np.nan, 30, 28],
    '收入': [8000, 12000, np.nan, 9500],
    '城市': ['北京', '上海', '广州', np.nan]
})

# 识别缺失值
print(df.isnull())

输出结果会是一个布尔矩阵:True表示缺失,False表示正常。我个人习惯用isnull(),当然你也可以用isna(),效果完全一样。

小技巧: 如果你想知道哪些行有缺失值,可以用 df[df.isnull().any(axis=1)]。这个我在项目里经常用来快速定位「问题行」。

3.2 缺失值统计:到底缺了多少?

识别出缺失值之后,下一步就是统计。说白了,你得知道每个字段缺了多少,占比多少,才能决定下一步怎么处理。

我常用的统计方法就两个:

# 方法1:统计每列缺失数量
print(df.isnull().sum())

# 方法2:统计每列缺失比例
print(df.isnull().mean())

输出结果:

字段 缺失数量 缺失比例
姓名 0 0%
年龄 1 25%
收入 1 25%
城市 1 25%

看到这个表格,你可能会想:「才25%的缺失,问题不大吧?」

别急。我在项目中遇到过这样的情况:某个字段缺失比例只有5%,但偏偏这5%的数据集中在某个特定时间段或特定用户群体里。这种「非随机缺失」才是最要命的。所以,光看比例还不够,还得看分布。

避坑指南: 我曾经接手过一个电商数据集,订单金额字段缺失率只有3%。我一开始觉得直接删除就行,结果发现这3%全是「大额订单」——因为系统在处理大额交易时有个bug,导致金额字段没写入。如果直接删掉,分析结果会严重低估客单价。所以,缺失比例低 ≠ 可以忽略

3.3 缺失值可视化:热力图

统计数字只能告诉你「缺了多少」,但热力图能告诉你「缺在哪里」。我个人非常喜欢用热力图来快速扫描整个数据集的缺失模式。

Python里最方便的工具是seabornheatmap

import seaborn as sns
import matplotlib.pyplot as plt

# 绘制缺失值热力图
plt.figure(figsize=(10, 6))
sns.heatmap(df.isnull(), cbar=False, cmap='viridis')
plt.title('缺失值热力图')
plt.show()

这张图里,黄色表示有数据,紫色表示缺失。一眼扫过去,你就能看到:

  • 哪些字段缺失严重(紫色区域大)
  • 缺失值是否集中在某些行(比如某几行全是紫色)
  • 不同字段的缺失是否有相关性(比如「年龄」和「收入」同时缺失)

你想想看,如果「年龄」和「收入」同时缺失的行特别多,那说明什么?很可能这些用户是同一批注册的,或者来自同一个数据源。这种模式光靠数字统计是看不出来的。

核心观点: 缺失值处理的第一步不是「怎么补」,而是「为什么缺」。热力图能帮你快速发现缺失模式,从而判断缺失是随机的还是有规律的。

3.4 知识体系:缺失值处理的完整流程

为了让你对整个流程有个全局认识,我画了一张图。这张图涵盖了从识别到处理的完整链路,咱们这一章只讲前三个步骤,后面几章会继续深入。

缺失值处理知识体系 步骤1:缺失值识别 isnull() / isna() 步骤2:缺失值统计 sum() / mean() 步骤3:缺失值可视化 热力图 / 条形图 步骤4:处理决策 删除 / 填充 / 插值 / 模型预测 步骤5:效果评估 对比处理前后分布 步骤6:迭代优化(根据业务反馈调整) ← 本章内容

这张图里,黄色标注的部分就是咱们这一章要讲的内容。后面的步骤,比如删除、填充、插值,咱们会在下一章详细展开。

3.5 实战小贴士

最后,分享几个我在实际项目中总结的经验:

  • 先看整体,再看局部。 先用isnull().sum()看全局,再用热力图看局部模式。
  • 别只看比例,要看绝对值。 100万条数据里缺失1%就是1万条,这个量级不能随便删。
  • 记录缺失模式。 我习惯在清洗文档里记一笔:「字段A缺失集中在某时间段,疑似系统bug」。这样后续分析时心里有数。
我的习惯: 每次拿到新数据集,第一件事就是跑一遍 df.info()df.isnull().sum()。这两个命令能让你在30秒内了解数据的基本健康状况。嗯,真的,30秒就够了。

好了,这一章就到这里。缺失值的识别、统计和可视化,是后续所有处理的基础。你把这些搞扎实了,后面处理起来就顺手多了。


公众号:蓝海数据掘金营,微信 deep3321