pd.isnull在DataFrame与单个元素上行为差异的原因探究
pd.isnull在Float64 dtype列上的行为不一致问题
我发现pd.isnull的行为存在不一致性:已知pd.isnull('nan')返回False,pd.isnull(float('nan'))返回True,因此我原本预期将pd.isnull应用于转换为'Float64' dtype的DataFrame列时,原字符串'nan'对应的结果应为True,但实际情况并非如此。
示例代码:
import pandas as pd import numpy as np df = pd.DataFrame([['1', pd.NA, 'nan'], ['re', 'ui1', np.nan]], columns=['a', 'b', 'c']) pd.isnull(df['c']) # [False, True] ==> 符合预期 pd.isnull(df.loc[0, 'c']) # False ==> 符合预期 pd.isnull(df[['c']].astype('Float64')) # [False, True] ==> 不符合预期? pd.isnull(df[['c']].astype('Float64').values) # [True, True] ==> 符合预期 pd.isnull(df[['c']].astype('Float64').loc[0, 'c']) # True ==> 符合预期
为什么pd.isnull在应用于整列或数据集时,与应用于单个元素的行为不同?我是否忽略了什么?
环境版本:
- Python 3.9.12
- pandas 2.2.3
- numpy 1.26.4
编辑补充:
转换为'float' dtype时不会出现此问题:
pd.isnull(df[['c']].astype('float')) # [True, True] ==> 符合预期
原因分析
这是因为pandas处理Float64(可空浮点类型)列的astype转换逻辑,与单个元素访问、numpy数组转换的逻辑存在差异:
- 整列
astype('Float64')转换:对字符串列执行该操作时,pandas不会自动将字符串'nan'转为Float64类型的缺失值pd.NA,该元素仍以字符串形式存在于Float64容器中,因此pd.isnull检查整列时返回False。 - 单个元素/数组转换:通过
.loc访问单个元素或用.values转numpy数组时,pandas会尝试将字符串'nan'解析为浮点缺失值np.nan,此时pd.isnull会识别为缺失值,返回True。 float与Float64的差异:转换为传统floatdtype时,pandas会强制将字符串'nan'转为np.nan,因为传统浮点类型没有可空容器,所以pd.isnull能正确识别。
解决方法
若要将字符串'nan'转为Float64类型的缺失值,可先用pd.to_numeric配合errors='coerce'处理:
df['c'] = pd.to_numeric(df['c'], errors='coerce').astype('Float64') pd.isnull(df['c']) # [True, True] ==> 符合预期
内容的提问来源于stack exchange,提问作者pommelador
相关产品推荐
相关产品推荐

