关于pandas中isna()对Float64类型下的NaN及pd.NA识别异常的疑问
Pandas中isna()对Float64类型下的NaN及pd.NA识别异常的疑问
嘿,这个问题确实挺容易让人摸不着头脑的,我来帮你拆解一下背后的核心原因:
1. 先搞清楚两种“缺失值”的区别
pandas里其实有两种不同的缺失值表示:
np.nan:这是numpy原生的浮点类型缺失值,属于传统的float64体系pd.NA:这是pandas为Nullable类型(比如Float64、Int64,注意大写开头)设计的统一缺失值标记
2. 你的代码里发生了什么?
- 你一开始把DataFrame转成了
Float64类型,这是pandas的Nullable浮点类型,专门用来支持pd.NA的。 - 当你执行
a.apply(lambda a:a/a.mean())时,列a的均值是0,0/0计算出来的是**np.nan**(因为numpy的算术运算默认返回原生的np.nan),但这个np.nan被存在了Float64类型的列里。 - 关键问题来了:
isna()在处理Nullable类型列时,只把pd.NA当作缺失值,而np.nan在这种类型里会被视为一个普通的“无效浮点值”,不会被标记为缺失。这是Nullable类型的设计逻辑——它希望用pd.NA统一管理缺失值,和传统的np.nan做区分。
3. 为什么转换类型后就正常了?
- 转成
object类型:这种类型对缺失值的判断是宽松的,不管是np.nan还是pd.NA,都会被isna()识别为缺失。 - 转成
float64(小写f):这是numpy的原生浮点类型,np.nan本来就是它的缺失值,而pd.NA会被自动转换成np.nan,所以两者都能被isna()识别。
你可以用这段小代码验证一下:
# 查看列a中第一个NaN的类型 print(type(a_nan['a'].iloc[0])) # 输出 <class 'float'>,说明是np.nan print(a_nan['a'].iloc[0] is pd.NA) # 输出 False,确认不是pd.NA print(pd.isna(a_nan['a'].iloc[0])) # 在Float64列中输出False,转成float64后会输出True
备注:内容来源于stack exchange,提问作者BobVitorBob




