为什么 pandas isnull() 有效但 ==None 无效?

raf*_*ffa 4 python python-3.x pandas

我正在尝试选择dflabel具有 value的行None。(这是None我从另一个函数获得的值,而不是NaN

为什么df[df['label'].isnull()]返回我想要的行,

df[df['label'] == None]返回Empty DataFrame Columns: [path, fanId, label, gain, order] Index: []

RK1*_*RK1 7

正如上面的评论所述,缺失的数据pandasNaN表示,其中NaN是一个数值,即浮点型。然而None是一个 Python NoneType,所以NaN不会等同于None

In [27]: np.nan == None
Out[27]: False
Run Code Online (Sandbox Code Playgroud)

在这个Github 线程中,他们进一步讨论,并指出:

这是很久以前完成的,以使空值的行为保持一致,因为它们比较不相等。这使 None 和 np.nan 处于平等(虽然与 python 不一致,但与 numpy 一致)的基础上。

这意味着当您这样做时df[df['label'] == None],您将elementwise检查 if np.nan == np.nan,我们知道这是错误的。

In [63]: np.nan == np.nan
Out[63]: False
Run Code Online (Sandbox Code Playgroud)

此外,df[df['label'] == None]在应用Boolean indexing时不应该这样做,正如PEP8提到的那样,使用==for aNoneType不是最佳实践:

与像 None 这样的单例的比较应该总是用isor来完成is not,而不是等号运算符。

例如,您可以执行tst.value.apply(lambda x: x is None),它产生与 相同的结果.isnull(),说明如何pandas将这些视为NaN注意这是下面的tst数据帧例如,在tst.value.dtypesobject其中我已经明确规定的NoneType内容。

有一个很好的例子pandas其中说明这个文档,它的效果。

例如,如果您有两列,一列是类型float,另一列是object您可以看到 pandas 如何None以一种很好的方式处理该类型,请注意float它使用的是NaN

In [32]: tst = pd.DataFrame({"label" : [1, 2, None, 3, None], "value" : ["A", "B", None, "C", None]})

Out[39]:
   label value
0    1.0     A
1    2.0     B
2    NaN  None
3    3.0     C
4    NaN  None

In [51]: type(tst.value[2])
Out[51]: NoneType

In [52]: type(tst.label[2])
Out[52]: numpy.float64
Run Code Online (Sandbox Code Playgroud)

这篇文章很好地解释了NaNNone之间的区别,肯定会看看这个。