因为int类型在pandas中不支持nan(底层为c int,无空值表示),强行转换会报valueerror;正确做法是先用pd.to_numeric(..., errors='coerce')转为float64并保留nan,再astype("int64")(首字母大写)转为可空整型。

为什么 astype 不能直接把含 NaN 的字符串列转成 int
因为 int 类型在 pandas 中不支持 NaN(底层是 C int,没有空值表示),一强行转就会报 ValueError: Cannot convert non-finite values (NA, NaN, INF) to integer。这不是数据脏,是类型系统硬限制。
常见场景:读 Excel 或 CSV 后,本该是数字的列被识别为 object(里面混着空格、空字符串、"N/A"、甚至真正的 NaN),你想用 astype(int) 清洗,结果崩了。
- 先用
pd.to_numeric(..., errors='coerce')把杂乱字符串统一转成float64(NaN自动保留) - 再考虑是否需要转成可空整型,比如
Int64(注意首字母大写,这是 pandas 的 nullable integer 类型) - 别用
astype(int)硬转——它不处理NaN,只会拒绝
用 astype("Int64") 替代 astype(int) 的实际效果
"Int64"(带引号、首字母大写)是 pandas 提供的可空整数类型,底层用 object + IntegerArray 实现,能安全存 NaN。和原生 int64 不兼容,但语义清晰、行为可控。
示例:
df["age"] = df["age"].astype("string").str.strip().replace("", pd.NA)
df["age"] = pd.to_numeric(df["age"], errors="coerce")
df["age"] = df["age"].astype("Int64") # ✅ 成功,NaN 变成 <na></na>
- 转换后
NaN显示为<na></na>,参与计算时仍按缺失值处理(如sum()自动跳过) - 导出到 CSV 时,
<na></na>默认写成空字段,和原始NaN行为一致 - 如果后续要传给 scikit-learn,得再填缺或转回
float64——它不认Int64
字符串列含 "NULL"、"None"、"nan" 字面量时怎么清理
这些不是真正的 NaN,而是字符串,pd.to_numeric 默认不会识别它们,会转成 NaN 并发出警告,但更稳妥的是先归一化。
- 用
.str.strip().str.lower().replace({"null": pd.NA, "none": pd.NA, "nan": pd.NA})预处理 - 避免直接
.replace("NULL", np.nan)——这会把所有列里叫 "NULL" 的值都改掉,不安全 - 对多列批量操作时,加
inplace=False和明确subset,防止误改其他列 - 检查残留:
df[col].apply(type).unique()能揪出还有哪些非字符串/非数值类型漏网
性能提示:大批量数据下 astype 的开销在哪
astype("Int64") 比 astype("float64") 内存高 2–3 倍,且算术运算慢约 30–50%,因为每步都要做 NA 分支判断。不是不能用,但得清楚代价。
- 纯计算场景(如 groupby + sum),用
float64更快,NaN不影响结果 - 需要保持整数语义(比如 ID、计数),且后续要导出或展示,才值得上
Int64 - 用
df.memory_usage(deep=True)对比前后,确认是否真有必要
真正容易被忽略的点:类型转换只是最后一步,前面的清洗逻辑(去空格、归一化字符串、判定缺失模式)往往占 80% 工作量。别急着 astype,先搞清数据到底长什么样。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











