Pandas 2.0启用PyArrow引擎后,"NA"不再自动识别为缺失值,因其严格仅将None和NaN映射为pd.NA;需在read_csv中用na_values显式声明或先replace再convert_dtypes。
Pandas 2.0 默认启用 PyArrow 引擎后,、、三者行为不再等价 ——成为统一缺失值标记,而仅保留在浮点列中;非标准字符串如、、空字符串默认不被识别为缺失值,必须显式声明。
为什么
不再自动变成
PyArrow 引擎(
)严格区分语义:它只将 Python
和 IEEE 754
映射为缺失,其余字符串一律视为有效数据。这与旧版 Pandas 的启发式推断(如自动把
当作缺失)完全不同。
读取 CSV 时,
不会解析
字段为缺失,除非你加
列中混有
和数字时,整列会被推断为
类型,
就是普通字符串,
对它返回
用
无法覆盖这些字符串,因为它们根本不是缺失值
如何让
、
等真正变成缺失值
必须在数据加载阶段就干预,靠后续
或
无法触发 PyArrow 的缺失语义(它们只改值,不改类型)。
CSV 场景:用
+
组合,避免 Pandas 自作主张把
也当缺失
已有 DataFrame:先用
把目标字符串转成
,再调用
强制重铸类型
注意:
单独执行不会生效,因为 PyArrow 列是不可变的,必须整列重赋值或调用
和
混用时的隐式转换陷阱
开启 PyArrow 后,混合数值列(如 int + float)若含
,会自动升格为
或
;但若误写
进整数列,Pandas 会静默转成
,破坏类型一致性。
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
下载
立即学习
“
Python免费学习笔记(深入)
”;
向整数列插入缺失值,务必用
,而非
或
(后者在 PyArrow 下可能被转成字符串)
安全;
会导致该列变成
,且后续
会失败
检查缺失值统一用
,不要用
—— 后者永远返回
Arrow 引擎下
和
的行为差异
参数逻辑没变,但底层判断依据变了:现在完全依赖 Arrow 的 null bitmap,而不是 Pandas 旧式的 object-dtype 推断。
只丢弃这两列中任一为
的行,
字符串不影响结果
中,若
是
,填入的
会被正确存为字符串;但若填
,则变成
,不是空字符串
性能上,Arrow 的
比旧引擎快 3–5 倍,但前提是列已用
正确标记 —— 错标成字符串就白优化了
最易忽略的一点:PyArrow 引擎不会帮你“猜”业务含义。一个字段里出现
,可能是缺失值,也可能是用户真实输入的短语。是否归为缺失,必须由你用
或
显式定义,没有中间态。
NoneNaNpd.NApd.NANaN"NA""NULL""NA"pd.NAdtype_backend="pyarrow"NoneNaN"NA"pd.read_csv(..., dtype_backend="pyarrow")"NA"na_values=["NA", "NULL", ""]"NA"string[pyarrow]"NA"df["col"].isna()Falsedf.fillna("missing")"NA""null".replace().map()na_valueskeep_default_na=False"nan"pd.read_csv("data.csv", na_values=["NA", "NULL", "N/A", ""], keep_default_na=False, dtype_backend="pyarrow").replace()None.convert_dtypes(dtype_backend="pyarrow")df = df.replace({"col": {"NA": None, "NULL": None}}).convert_dtypes(dtype_backend="pyarrow")df["col"] = df["col"].replace(...)convert_dtypespd.NANaNpd.NAInt64[pyarrow]double[pyarrow]np.nanfloat64pd.NAnp.nanNonedf["age"] = df["age"].fillna(pd.NA)df["age"] = df["age"].fillna(np.nan)float64.astype("int64[pyarrow]")df.isna()df == np.nanFalsedropna()fillna()df.dropna(subset=["col1", "col2"])pd.NA"NA"df.fillna({"col1": 0, "col2": "unknown"})col2string[pyarrow]"unknown"Nonepd.NAdropnapd.NA"N/A"na_valuesreplace