df.isna().sum()可快速统计每列空值数量,返回含列名索引的Series;需注意其仅识别NaN、None、NaT,不识别'NULL'等字符串;可构建含缺失数、占比、数据类型的结构化报告。

用 isna() + sum() 快速统计每列空值数量
直接对 DataFrame 调用 df.isna().sum() 就能得到各列空值计数,这是最轻量、最常用的方式。它返回一个 Series,索引是列名,值是对应列的 True(即空值)个数。
注意:这里的“空值”指所有被 Pandas 视为缺失的值——NaN、None、NaT(时间类型),但不包括字符串 'NULL'、'N/A' 或空白字符串 '',这些需额外处理。
常见错误现象:df.isnull().sum() 也能用(isnull() 是 isna() 的别名),但建议统一用 isna(),语义更清晰;误写成 df.isna.sum()(漏了括号)会报 AttributeError。
输出结构化报告:转成 DataFrame 并添加百分比列
单纯看数字不够直观,加一列占比能快速定位问题列。关键点在于:总行数要用 len(df),不是 df.shape[0](二者等价,但 len() 更直觉),且必须处理分母为 0 的边界情况(空表)。
立即学习“Python免费学习笔记(深入)”;
nan_report = df.isna().sum().rename('missing_count')
nan_report = nan_report.to_frame()
nan_report['missing_pct'] = (nan_report['missing_count'] / len(df) * 100).round(2)
nan_report['dtype'] = df.dtypes
使用场景:生成数据质量快照、ETL 前校验、Jupyter 中快速诊断。若列数多,可加 nan_report[nan_report['missing_count'] > 0] 只显示有空值的列。
性能影响:对百万级以下数据无感;若 DataFrame 极宽(上千列),isna() 本身是逐元素判断,但整体仍远快于循环 + isna().sum() 每列调用一次。
区分不同空值类型:单独检查 None 和 NaN 的分布
isna() 把 None 和 NaN 都标为 True,但它们底层行为不同(比如 None 在 object 列中更常见,NaN 多出现在数值列)。如需拆开统计:
-
df.apply(lambda s: s.isna().sum() - s.isnull().sum())没用——两者结果完全一致 - 正确方式是用
df.apply(lambda s: s.apply(type).eq(type(None)).sum())统计显式None(但极慢,仅调试用) - 更实用的是:对 object 列,用
df[col].apply(lambda x: x is None);对数值列,np.isnan(df[col])更准(因None在数值列会被自动转成NaN)
容易踩的坑:在数值列里用 x is None 判断永远为 False(因为 None 已被转成 NaN);用 pd.isna(x) 才安全通用。
导出报告到 Excel 或打印时控制格式
直接 print(nan_report) 在终端可能换行混乱,尤其列名长或含中文。推荐:
- 终端查看:加
pd.set_option('display.max_columns', None)和'display.width', 120 - 导出 Excel:
nan_report.to_excel('missing_report.xlsx', index=True),注意index=True才保留列名作为首列 - 避免科学计数法:对
missing_pct列,用.map('{:.2f}%'.format)替代.round(2),防止小数位丢失
兼容性提醒:to_excel 需安装 openpyxl 或 xlsxwriter;若只读 CSV,用 to_csv(..., encoding='utf-8-sig') 防止 Excel 打开中文乱码。
真正麻烦的不是统计空值,而是空值背后的原因——同一列里混着 NaN、空字符串、占位符字符串,这时候 isna() 就完全看不见了,得先做清洗再统计。


















