通过pd.notnull进行空值检查的行为很奇怪

3
这基本上是我在这里的答案的内容重新排列:这里
在尝试使用pd.notnull解决这个问题时,我遇到了一些奇怪的行为。
考虑以下内容:
x = ('A4', nan)

我想检查这些项目中哪些是空的。直接使用 np.isnan 会抛出 TypeError (但我已经找到了解决方法)。
使用 pd.notnull 不起作用。
>>> pd.notnull(x)
True

它把元组看作一个单一的值(而不是值的可迭代对象)。此外,将其转换为列表然后进行测试也会给出错误的答案。

>>> pd.notnull(list(x))
array([ True,  True])

由于第二个值是 nan,所以我要寻找的结果应该是 [True, False]。当您预先转换为序列时,最终会起作用:
>>> pd.Series(x).notnull() 
0     True
1    False
dtype: bool

所以,解决方案是将其转换为Series,然后测试值。
类似的,另一种(虽然迂回)解决方案是预先将其转换为object dtype的numpy数组,然后pd.notnullnp.isnan直接起作用:
>>> pd.notnull(np.array(x, dtype=object))
Out[151]: array([True,  False])

我想象中,pd.notnull 在底层直接将 x 转换为字符串数组,将 NaN 渲染为字符串 "nan",因此它不再是一个 "null" 值。
在这里,pd.notnull 是否也在做同样的事情?还是底层发生了其他事情,我应该注意到吗? 注:
In [156]: pd.__version__
Out[156]: '0.22.0'

你使用的是哪个版本的 pandas?在 v. 23.0 中,pd.notnull(list(x)) 返回正确的结果:array([ True, False]) - Grigoriy Mikhalkin
@GrigoriyMikhalkin 0.22。如果在0.23上不存在此问题,则肯定是已经修复的错误。有趣。 - cs95
pandas 0.23.1 中测试 - x = ('A4', np.nan) print(pd.notnull(list(x))) 并返回 [ True False] - jezrael
@coldspeed 看起来这个问题与以下行为有关:https://github.com/pandas-dev/pandas/issues/20675 - Grigoriy Mikhalkin
@GrigoriyMikhalkin 完美。这就是答案。谢谢。 - cs95
@GrigoriyMikhalkin 如果你愿意的话,写几句话作为答案,我很乐意标记它。 - cs95
1个回答

3
这里涉及到的问题是:https://github.com/pandas-dev/pandas/issues/20675
简单来说,如果传递给“notnull”参数的类型为“list”,则内部会使用“np.asarray”方法将其转换为“np.array”。该Bug发生的原因是,如果未指定“dtype”,numpy会将“np.nan”转换为“string”(而这不被“pd.isnull”识别为null值):
a = ['A4', np.nan]
np.asarray(a)
# array(['A4', 'nan'], dtype='<U3')

这个问题在0.23.0版本中得到解决,方法是使用dtype=object调用np.asarray函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接