Pandas 的 int64 等原始整型不支持 NaN,因 NumPy 整型数组禁止非有限值;应改用首字母大写的可空类型 Int64,它原生支持 pd.NA 和 np.nan,并需注意导出时的缺失值表示兼容性。

为什么直接用 int 类型列存 NaN 会报错
Pandas 的原始 int64(或 int32 等)dtype 不支持 NaN,因为底层 NumPy 的整型数组不允许 NaN——它会被强制转成 float64,或者抛出 ValueError: Cannot convert non-finite values (NA, NaN, INF) to integer。这不是 Pandas 的 bug,而是整型语义决定的:整数没有“缺失”这个合法值。
常见触发场景:df['col'].fillna(0).astype(int) 在含 NaN 时失败;读 CSV 时列本应是整数但有空单元格,pd.read_csv() 默认推断为 float64;或用 loc 赋值 np.nan 到 int 列后类型未更新。
用 Int64(首字母大写)替代 int64
Pandas 自 0.24+ 提供了可空整型扩展类型 Int64、Int32、Int16 和 Int8(注意首字母大写),它们底层用对象数组或位掩码存储,原生支持 pd.NA 和 np.nan(自动转换)。
- 显式转换:
df['col'] = df['col'].astype('Int64')—— 若原列是 float 且只含整数值和NaN,会成功;若含小数,会报ValueError - 读取 CSV 时指定:
pd.read_csv('data.csv', dtype={'col': 'Int64'}) - 新建列时直接用:
df['new_col'] = pd.array([1, 2, None, 4], dtype='Int64') -
pd.NA是推荐的缺失值表示,比np.nan更语义清晰;但np.nan赋值也会被自动转为pd.NA
fillna() 后再转 Int64 还是直接用扩展类型?
取决于业务意图。如果缺失值有明确默认含义(如“未填写=0”),填充值再转 Int64 没问题;但如果缺失本身是有效信息(如“该用户未参与活动”),强行填 0 或 -1 会污染统计结果,此时保留 Int64 + pd.NA 更安全。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
立即学习“Python免费学习笔记(深入)”;
- 填 0 再转:
df['col'].fillna(0).astype('Int64')—— 注意:若原列是float64且含3.0,填完仍是浮点,需加.round().astype('Int64') - 不填、直接升为可空类型:
df['col'] = df['col'].astype('Int64')—— Pandas 会把np.nan自动映射为pd.NA - 聚合时注意:
df['col'].sum()默认跳过pd.NA,和skipna=True行为一致;但df['col'].mean()返回float64,不是Int64
导出到 CSV 或数据库时的兼容性陷阱
Int64 列写入 CSV 默认会把 pd.NA 输出为空字符串(''),而非 NaN 或 NULL,这可能导致下游系统误解析。数据库写入(如 SQLAlchemy)也可能因驱动不识别 pd.NA 而报错。
- 导出 CSV 时显式控制缺失值表示:
df.to_csv('out.csv', na_rep='NULL') - 写入数据库前转换缺失值:
df['col'] = df['col'].replace({pd.NA: None})(SQLAlchemy 接受None为 NULL) - 检查 dtype 是否真生效:
df['col'].dtype应返回Int64(不是int64),大小写敏感 - 旧版本 Pandas(float64 +
NaN,或手动引入pd.Int64Dtype()对象
最易忽略的是:用 df.dtypes 查看时,Int64 和 int64 在输出里长得像,但前者是 extension dtype,后者是原始 NumPy dtype——差一个字母,行为天壤之别。

















