当前位置: 首页 > 知识库问答 >
问题:

比较NumPy数组,使NaNs比较相等

阎卓
2023-03-14

是否有一种惯用的方法来比较两个NumPy数组,它们将NaN视为彼此相等(但不等于NaN以外的任何东西)。

例如,我希望以下两个数组比较相等:

np.array([1.0, np.NAN, 2.0])
np.array([1.0, np.NAN, 2.0])

和以下两个数组进行比较:

np.array([1.0, np.NAN, 2.0])
np.array([1.0, 0.0, 2.0])

我正在寻找一种可以产生标量布尔结果的方法。

以下方法可以做到这一点:

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

但它很笨重,并且创建了所有这些中间数组。

有没有一种方法可以更容易地观察眼睛,更好地利用记忆?

另外,如果有帮助的话,已知数组具有相同的形状和数据类型。

共有3个答案

方权
2023-03-14

免责声明:我不建议经常使用这个,我自己也不会使用它,但是我可以想象在极少数情况下它可能会有用。

如果数组具有相同的形状和dType,可以考虑使用低级<代码> MeMyVIEW < /代码>:

>>> import numpy as np
>>> 
>>> a0 = np.array([1.0, np.NAN, 2.0])
>>> ac = a0 * (1+0j)
>>> b0 = np.array([1.0, np.NAN, 2.0])
>>> b1 = np.array([1.0, np.NAN, 2.0, np.NAN])
>>> c0 = np.array([1.0, 0.0, 2.0])
>>> 
>>> memoryview(a0)
<memory at 0x85ba1bc>
>>> memoryview(a0) == memoryview(a0)
True
>>> memoryview(a0) == memoryview(ac) # equal but different dtype
False
>>> memoryview(a0) == memoryview(b0) # hooray!
True
>>> memoryview(a0) == memoryview(b1)
False
>>> memoryview(a0) == memoryview(c0)
False

但要小心这样的微妙问题:

>>> zp = np.array([0.0])
>>> zm = -1*zp
>>> zp
array([ 0.])
>>> zm
array([-0.])
>>> zp == zm
array([ True], dtype=bool)
>>> memoryview(zp) == memoryview(zm)
False

这是因为二进制表示不同,即使它们比较相等(当然,它们必须这样做:这就是它知道如何打印负号的原因)

>>> memoryview(zp)[0]
'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> memoryview(zm)[0]
'\x00\x00\x00\x00\x00\x00\x00\x80'

从好的方面来看,它会像你希望的那样短路:

In [47]: a0 = np.arange(10**7)*1.0
In [48]: a0[-1] = np.NAN    
In [49]: b0 = np.arange(10**7)*1.0    
In [50]: b0[-1] = np.NAN     
In [51]: timeit memoryview(a0) == memoryview(b0)
10 loops, best of 3: 31.7 ms per loop
In [52]: c0 = np.arange(10**7)*1.0    
In [53]: c0[0] = np.NAN   
In [54]: d0 = np.arange(10**7)*1.0    
In [55]: d0[0] = 0.0    
In [56]: timeit memoryview(c0) == memoryview(d0)
100000 loops, best of 3: 2.51 us per loop

作为比较:

In [57]: timeit np.all((a0 == b0) | (np.isnan(a0) & np.isnan(b0)))
1 loops, best of 3: 296 ms per loop
In [58]: timeit np.all((c0 == d0) | (np.isnan(c0) & np.isnan(d0)))
1 loops, best of 3: 284 ms per loop
漆雕兴平
2023-03-14

Numpy 1.10将equal_nan关键字添加np.allclose(https://docs.scipy.org/doc/numpy/reference/generated/numpy.allclose.html).

所以你现在可以做:

In [24]: np.allclose(np.array([1.0, np.NAN, 2.0]), 
                     np.array([1.0, np.NAN, 2.0]), equal_nan=True)
Out[24]: True
欧阳楚
2023-03-14

如果您真的关心内存使用(例如,拥有非常大的数组),那么您应该使用numexpr,以下表达式适用于您:

np.all(numexpr.evaluate('(a==b)|((a!=a)&(b!=b))'))

我已经在非常大的数组(长度为3e8)上测试了它,代码在我的机器上的性能与

np.all(a==b)

并使用相同数量的内存

 类似资料:
  • 比较两个NumPy数组是否相等的最简单方法是什么(其中相等定义为:A=B iff,用于所有索引i:

  • 问题内容: 在对某些功能进行单元测试的上下文中,我试图使用python pandas建立2个DataFrames的相等性: 鉴于我正在尝试针对的完整测试(包括职位),我在做什么错? 比较包含s的Series / DataFrames相等性的最简单方法是什么? 问题答案: 您可以将assert_frame_equals与check_names = False一起使用(以免检查索引/列名称),如果它们

  • 问题内容: 对于我的单元测试,我想检查两个数组是否相同。简化示例: 这是行不通的,因为。最好的进行方法是什么? 问题答案: 或者您可以使用或用: 编辑 由于您正在使用它进行单元测试,因此裸露(而不是将其包装成get )可能更自然。

  • 我的问题是"为什么?:" 这些数组完全相同。 我的最小示例并没有再现这一点: 这个也没有: 我不知道为什么这些不平等。还有一个额外的问题,我如何比较它们? 我需要一种有效的方法来检查aaa是否在堆栈aa中。 我没有在aa中使用

  • 因此,我有两个大小相等的2D numpy数组,都是在两个不同的曲面上使用方法获得的。 数组中的每个值也是形式的数组(所以我基本上有一个带有1D元素的2D数组)。 基本上,我想根据条件对两者进行比较: 有没有更有效的方法可以做到这一点,而无需简单地迭代任何一个数组,如下所示?

  • 我的任务是用java编写mergesort,任务还规定我不能使用整数,我必须使用可比较的整数。这是我第一次使用java。我的问题是在合并函数内比较两个comp int数组中的元素。我尝试了if(list[I])compareTo(list2[j]),但compareTo只能取整数。任何帮助都将不胜感激