首页 > 解决方案 > 为什么 pandas isnull() 有效但 ==None 无效?

问题描述

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

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

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

标签: pythonpython-3.xpandas

解决方案


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

In [27]: np.nan == None
Out[27]: False

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

这是很久以前完成的,以使 null 的行为保持一致,因为它们不比较相等。这使 None 和 np.nan 处于平等地位(尽管与 python 不一致,但与 numpy 一致)。

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

In [63]: np.nan == np.nan
Out[63]: False

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

与 None 等单例的比较应始终使用isor完成,而不应使用is not相等运算符。

例如,您可以这样做tst.value.apply(lambda x: x is None),产生与 相同的结果.isnull(),说明如何pandas将这些视为NaN请注意,这是针对以下tst数据框示例的,其中tst.value.dtypes一个object是我明确指定的NoneType元素。

文档中有一个很好的例子说明了这一点及其效果。pandas

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

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

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


推荐阅读