4. 缺失值检测:isnull()、sum()、isna() 与可视化

缺失值是数据质量检查中最常见的问题之一。在 Pandas 中,isnull() 和 isna() 是检测缺失值的核心方法,配合 sum() 可以快速统计每列的缺失数量。可视化工具(热力图、条形图)则能直观展示缺失模式,帮助判断缺失是随机分布还是存在系统性偏差。

4.1 核心检测方法对比

方法 返回值 适用场景 备注
isnull() 布尔型 DataFrame 通用缺失检测 NaN / None / NaT 均视为缺失
isna() 布尔型 DataFrame 与 isnull() 完全等价 别名,推荐用于语义清晰
notna() 布尔型 DataFrame 检测非缺失值 与 isna() 逻辑相反
sum() Series(每列缺失计数) 统计缺失总量 True 计为 1,False 计为 0
最佳实践: 使用 df.isna().sum() 一行代码即可获得全表缺失值概览。若需查看缺失比例,可配合 df.isna().mean() 得到每列缺失率。

4.2 基础代码示例

import pandas as pd
import numpy as np

# 构造含缺失值的示例数据
df = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六', None],
    '年龄': [25, None, 30, 22, 28],
    '工资': [5000, 6000, None, 5500, 6200],
    '入职日期': pd.to_datetime(['2020-01-15', '2021-03-20', None, '2019-07-01', '2022-11-10'])
})

# 1. 检测缺失值(布尔矩阵)
print("缺失值布尔矩阵:")
print(df.isna())

# 2. 统计每列缺失数量
print("\n每列缺失数量:")
print(df.isna().sum())

# 3. 统计缺失比例
print("\n每列缺失比例:")
print(df.isna().mean())

# 4. 查看总缺失数
total_missing = df.isna().sum().sum()
print(f"\n数据表总缺失数:{total_missing}")

4.3 缺失值可视化

可视化能快速揭示缺失模式:缺失是随机散布还是集中在某些列/行?是否存在块状缺失?以下两种图形是数据质量检查的标准工具。

4.3.1 缺失值热力图

热力图以颜色深浅直观显示缺失位置,适合快速定位缺失集中区域。

import matplotlib.pyplot as plt
import seaborn as sns

# 绘制缺失值热力图
plt.figure(figsize=(10, 6))
sns.heatmap(df.isna(), cbar=False, cmap='viridis', yticklabels=False)
plt.title('缺失值热力图(黄色=缺失,紫色=非缺失)')
plt.xlabel('列名')
plt.ylabel('行索引')
plt.tight_layout()
plt.show()
缺失值热力图概念示意 非缺失 缺失 行0 行1 行2 行3 行4 姓名 年龄 工资 入职日期 红色单元格表示该位置存在缺失值,绿色表示数据完整 热力图可快速发现缺失是否集中在特定列或行

4.3.2 缺失值条形图

条形图展示每列缺失数量的排序分布,适合对比不同列的缺失严重程度。

# 绘制缺失值条形图
missing_counts = df.isna().sum()
missing_counts = missing_counts[missing_counts > 0].sort_values(ascending=False)

plt.figure(figsize=(8, 5))
missing_counts.plot(kind='bar', color='#e74c3c', edgecolor='#c0392b')
plt.title('各列缺失值数量分布')
plt.xlabel('列名')
plt.ylabel('缺失数量')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
缺失值条形图概念示意 2 1 0 工资 2 年龄 1 姓名 1 入职日期 1 条形图按缺失数量降序排列,帮助优先处理缺失严重的列 红色表示缺失数量 ≥2,橙色表示缺失数量 =1

4.4 缺失模式分析流程

  1. 初步统计: 使用 df.isna().sum() 获取每列缺失数量,df.isna().mean() 获取缺失率。
  2. 可视化探查: 绘制热力图观察缺失分布模式(随机 / 块状 / 列集中)。
  3. 排序对比: 绘制条形图按缺失数量排序,识别高缺失列。
  4. 关联分析: 检查缺失是否与其他列存在关联(例如某列缺失时另一列也缺失)。
  5. 决策: 根据缺失比例和模式选择填充、删除或标记策略。
常见陷阱: 空字符串 '' 和字符串 'NaN' 不会被 isna() 识别为缺失值。需先使用 replace() 或 mask() 将其转换为真正的 NaN。

4.5 进阶:缺失值关联检测

有时缺失并非独立事件。以下代码检测两列缺失是否同时发生:

# 检测两列是否同时缺失
both_missing = df['年龄'].isna() & df['工资'].isna()
print(f"年龄和工资同时缺失的行数:{both_missing.sum()}")

# 缺失关联矩阵(热力图变体)
missing_corr = df.isna().corr()
print("\n缺失值相关系数矩阵:")
print(missing_corr)
关键指标: 缺失相关系数接近 1 表示两列缺失高度同步,可能存在数据采集层面的系统性原因(如同一设备故障导致多个字段缺失)。