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】:
由于 a
和 b
是列表,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 graph_numpy_matrix_with_nan