Python\Numpy:将数组与 NAN 进行比较 [重复]

Posted

技术标签:

【中文标题】Python\\Numpy:将数组与 NAN 进行比较 [重复]【英文标题】:Python\Numpy: Comparing arrays with NAN [duplicate]Python\Numpy:将数组与 NAN 进行比较 [重复] 【发布时间】:2014-07-11 16:48:15 【问题描述】:

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

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.in1d(a, b) 似乎np.NAN 值不相等,但我不确定这是为什么。任何人都可以对这个问题有所了解吗?

【问题讨论】:

我觉得@DSM 的回答给出了我正在使用的解决方法,因此将其选为最佳答案 我看不出这个问题如何被认为是重复的,可能还有其他类似的问题,但是链接为重复的问题是关于 IEEE 实现(为什么是 nan != nan),甚至没有提到数组。 【参考方案1】:

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

所以[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 = 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 的列表将与自身比较(尽管可以说它不应该如此)。 @ZeroPiraeus:是的,确实如此。我怀疑这是因为 Python “捷径”了元素比较,如果您将列表与自身进行比较,则只返回 True,这胜过“正确”结果。这似乎是一个合理的优化:如果其中可能有一个 NaN,那么减慢每个列表与自我比较的速度是没有意义的。 您可以通过执行 ` x != x, which is how NumPy does this in the source C code, see e.g. [here](https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/arraytypes.c.src#L2456). So in pure Python you can do all(j == k or (j != j and k != k) for j 来获得 math.isnan(x) 的稍快版本, k 在 zip(a, b))` 中检查是否相等。 a = [1, np.nan]; b = [1, np.nan]; a == b 仍然返回 True。不过,我找不到为什么会这样。【参考方案2】:

由于 ab 是列表,a == b 不会返回数组,因此您的类似 numpy 的逻辑将不起作用:

>>> a == b
False

您引用的命令仅在它们是 数组 时才有效:

>>> 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

这应该可以比较两个数组(它们都相等或都是 NaN)。

【讨论】:

感谢刚刚意识到这一点。我会尝试解决方法。【参考方案3】:

NaN 根据 IEEE 754(参见 http://en.wikipedia.org/wiki/NaN)在 python(和 numpy)中实现,并定义为无序。在实践中,这意味着 NaN 在有序比较操作中永远不会返回 True,例如<>== 等 numpy 和内置的math 模块提供isnan 函数来确定一个值是否为NaN。

【讨论】:

以上是关于Python\Numpy:将数组与 NAN 进行比较 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

有效地检查 Python / numpy / pandas 中的任意对象是不是为 NaN?

python numpy 和内存效率(通过引用与值传递)

python graph_numpy_matrix_with_nan

如何将长双打与 qsort 以及关于 NaN 进行比较?

python数据分析 python numpy--数组--运算,切片和索引

python数据分析 python numpy--函数和数组运算