Pandas使用.isin()方法检查NaN值不起作用。

4

我有一个带有 NaN 的pandas数据框。

import pandas as pd
df = pd.DataFrame([1,2,3,float('nan')], columns=['A'])
df

    A
0   1
1   2
2   3
3 NaN

我还有一个名为filter_list的列表,我想用它来筛选我的数据框。但是如果我使用.isin()函数,它无法检测到NaN值。在最后一行,我得到了False而不是True

filter_list = [1, float('nan')]

df['A'].isin(filter_list)
0     True
1    False
2    False
3    False
Name: A, dtype: bool

预期输出:

0     True
1    False
2    False
3    True
Name: A, dtype: bool

我知道我可以使用.isnull()来检查NaN,但是这里我还有其他值要检查。我正在使用pandas 0.16.0版本。
编辑:列表filter_list来自用户。因此它可能有也可能没有NaN。这就是我为什么使用.isin()的原因。

1
这段代码行不通,因为 np 的实现依赖于 NaN != NaN 这一事实,所以会导致失败。因此,你需要先过滤掉所有的 NaN 值,然后再过滤其他数值。 - EdChum
有没有一种方法可以在filter_list中创建NaN元素,以便pandas能够理解它? - Kathirmani Sukumar
1
不,我不这么认为。例如df['A'] == float('nan')仍然无法工作,最重要的是你必须使用isnullnotnull来正确测试NaN - EdChum
1
清理您的用户输入!不要让他们输入NaN!使用适当的NA值填充fillna,并对用户输入执行相同操作。 - firelynx
4个回答

7

浮点数NaN有一个有趣的特性,它不等于自身

In [194]: float('nan') == float('nan')
Out[194]: False

isin 检查相等性。因此,您不能使用 isin 检查一个值是否等于 NaN。 要检查 NaN,最好使用 np.isnull


In [200]: df['A'].isin([1]) | df['A'].isnull()
Out[200]: 
0     True
1    False
2    False
3     True
Name: A, dtype: bool

问题在于列表filter_list来自用户。因此它可能有也可能没有NaN - Kathirmani Sukumar
2
要么改变用户界面,使filter_nan成为一个额外的参数,不包括NaN在filter_list中,或者检查pd.isnull(filter_list).any()并相应处理这些情况。 - unutbu

6
您可以将 nan 替换为一个唯一的非 NaN 值,该值不会出现在您的列表中,例如 'NA'''。 例如:
In [23]: import pandas as pd

In [24]: df = pd.DataFrame([1, 2, 3, pd.np.nan], columns=['A'])

In [25]: filter_list = pd.Series([1, pd.np.nan])

In [26]: na_equiv = 'NA'

In [27]: df['A'].replace(pd.np.nan, na_equiv).isin(filter_list.replace(pd.np.nan, na_equiv))
Out[27]:
0     True
1    False
2    False
3     True
Name: A, dtype: bool

2

我认为最简单的方法是使用numpy.nan

import pandas as pd
import numpy as np

df = pd.DataFrame([1, 2, 3, np.nan], columns=['A'])
filter_list = [1, np.nan]
df['A'].isin(filter_list)

1
如果你真的想使用isin()来匹配NaN。您可以创建一个具有与nan相同哈希值的类,并在与nan比较时返回True:
import numpy as np
import pandas as pd

class NAN(object):
    def __eq__(self, v):
        return np.isnan(v)

    def __hash__(self):
        return hash(np.nan)

nan = NAN()

df = pd.DataFrame([1,2,3,float('nan')], columns=['A'])
df.A.isin([1, nan])

1
更简单的选项是编写以下内容:import numpy as npdf = pd.DataFrame([1,2,3,np.nan], columns=['A']) - shahar

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