Python\Numpy:将数组与NAN进行比较

Python\Numpy:将数组与NAN进行比较,python,numpy,Python,Numpy,为什么以下两个列表不相等 a = [1.0, np.NAN] b = np.append(np.array(1.0), [np.NAN]).tolist() 我使用下面的方法来检查一致性 ((a == b) | (np.isnan(a) & np.isnan(b))).all(), np.in1d(a,b) 使用np.inad(a,b)似乎np.NAN值不相等,但我不确定这是为什么。有人能解释一下这个问题吗 NaN值的比较永远不相等。也就是说,根据NaN的定义,测试NaN==NaN

为什么以下两个列表不相等

a = [1.0, np.NAN] 
b = np.append(np.array(1.0), [np.NAN]).tolist()
我使用下面的方法来检查一致性

((a == b) | (np.isnan(a) & np.isnan(b))).all(), np.in1d(a,b)

使用
np.inad(a,b)
似乎
np.NAN
值不相等,但我不确定这是为什么。有人能解释一下这个问题吗

NaN
值的比较永远不相等。也就是说,根据
NaN
的定义,测试
NaN==NaN
总是
False

所以
[1.0,NaN]=[1.0,NaN]
也是
False
。事实上,一旦一个
NaN
出现在任何列表中,它就无法与任何其他列表进行比较,即使是它本身

如果要在
numpy
中测试变量是否为
NaN
,请使用
numpy.isnan()
函数。除了通过循环“手动”迭代列表之外,我看不到任何明显的方法来获得您似乎想要的比较语义

考虑以下几点:

import math
import numpy as np

def nan_eq(a, b):
    for i,j in zip(a,b):
        if i!=j and not (math.isnan(i) and math.isnan(j)):
            return False
    return True

a=[1.0, float('nan')]
b=[1.0, float('nan')]

print( float('nan')==float('nan') )
print( a==a )
print( a==b )
print( nan_eq(a,a) )
它将打印:

False
True
False
True

测试
a==a
之所以成功,大概是因为Python认为对同一对象的引用是相等的,而不是
a==b
所要求的元素级比较的结果。

因为
a
b
是列表,
a==b
没有返回数组,所以你的numpy逻辑不起作用:

>>> a == b
False
您引用的命令仅适用于以下阵列:


这可以用来比较两个数组(或者它们都相等,或者它们都是NaN)。

NaN根据IEEE 754(请参阅)用python(和numpy)实现,并定义为无序。在实践中,这意味着NaN在有序比较操作(例如,
==
等)中从不返回True。numpy和内置的
数学
模块提供
isnan
函数来确定值是否为NaN

谢谢。这很奇怪,因为我可以使用
a=np.array([1.0,np.NAN]),b=np.append(np.array(1.0),[np.NAN])
使用
((a==b)|(np.isnan(a)和np.isnan(b))。all()
事实上答案并不完全正确:在Python中,包含NAN的列表将与自身进行比较(尽管可以说它不应该如此)。@Zeroaeus:是的,的确如此。我怀疑这是因为Python“捷径”了元素级比较,如果将列表与自身进行比较,它只返回
True
,而这胜过了“正确”的结果。这似乎是一个合理的优化:与self-down相比,没有必要降低每个列表的速度,因为其中可能存在NaN。通过执行'x!=x
,这是NumPy在源C代码中如何做到这一点的,请参见示例[此处](https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/arraytypes.c.src#L2456). 因此,在纯Python中,您可以对zip(a,b)中的j,k执行
all(j==k或(j!=j和k!=k))`来检查是否相等;b=[1,np.nan];a==b仍然返回True。不过我不明白为什么会这样。谢谢,我刚刚意识到了这一点。我将尝试一种变通方法。我觉得@DSM的答案给出了我正在使用的变通方法,因此将其作为首选答案。我不知道这个问题如何被视为重复的,可能还有其他类似的问题,但链接为重复的问题是关于IEEE实现的(为什么nan!=nan),甚至没有提到数组。
>>> a,b = np.asarray(a), np.asarray(b)
>>> a == b
array([ True, False], dtype=bool)
>>> (a == b) | (np.isnan(a) & np.isnan(b))
array([ True,  True], dtype=bool)
>>> ((a == b) | (np.isnan(a) & np.isnan(b))).all()
True