比较含有NaN的numpy数组

时间:2012-05-22 21:18:47

标签: python numpy

对于我的unittest,我想检查两个数组是否相同。简化示例:

a = np.array([1, 2, np.NaN])
b = np.array([1, 2, np.NaN])
if np.all(a==b):
    print 'arrays are equal'

这不起作用,因为nan!= nan。 最好的方法是什么?

提前致谢。

10 个答案:

答案 0 :(得分:32)

我不确定这是最好的方式,但它是 a 方式:

>>> ((a == b) | (numpy.isnan(a) & numpy.isnan(b))).all()
True

答案 1 :(得分:31)

或者,您可以numpy.testing.assert_equal使用numpy.testing.assert_array_equal或{{3}}:

try/except

修改

由于您正在使用它进行单元测试,因此裸In : import numpy as np In : def nan_equal(a,b): ...: try: ...: np.testing.assert_equal(a,b) ...: except AssertionError: ...: return False ...: return True In : a=np.array([1, 2, np.NaN]) In : b=np.array([1, 2, np.NaN]) In : nan_equal(a,b) Out: True In : a=np.array([1, 2, np.NaN]) In : b=np.array([3, 2, np.NaN]) In : nan_equal(a,b) Out: False (而不是将其包装为获取assert)可能更自然。

答案 2 :(得分:17)

最简单的方法是使用numpy.allclose()方法,该方法允许在具有nan值时指定行为。然后您的示例将如下所示:

a = np.array([1, 2, np.nan])
b = np.array([1, 2, np.nan])

if np.allclose(a, b, equal_nan=True):
    print 'arrays are equal'

然后会打印arrays are equal

您可以找到here相关文档

答案 3 :(得分:8)

您可以使用numpy蒙面数组,屏蔽NaN值,然后使用numpy.ma.allnumpy.ma.allclose

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.all.html

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.allclose.html

例如:

a=np.array([1, 2, np.NaN])
b=np.array([1, 2, np.NaN])
np.ma.all(np.ma.masked_invalid(a) == np.ma.masked_invalid(b)) #True

答案 4 :(得分:4)

当我使用上述答案时:

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

在评估字符串列表时,它给了我一些错误。

这是更通用的类型:

def EQUAL(a,b):
    return ((a == b) | ((a != a) & (b != b)))

答案 5 :(得分:2)

只需完成@Luis Albert Centeno’s answer,您就可以使用:

np.allclose(a, b, rtol=0, atol=0, equal_nan=True)

rtolatol控制相等性测试的容差。简而言之,allclose()返回:

all(abs(a - b) <= atol + rtol * abs(b))

默认情况下,它们未设置为0,因此如果您的数字接近但不完全相等,则该函数可能返回True


PS:“我要检查两个数组是否相同。 “ >> 实际上,您正在寻找的是平等,而不是身份。它们在Python中并不相同,我认为每个人最好理解它们之间的差异,以便共享相同的词典。 (https://www.blog.pythonlibrary.org/2017/02/28/python-101-equality-vs-identity/

您将通过关键字is测试身份:

a is b

答案 6 :(得分:0)

如果您是针对单元测试之类的东西这样做的,那么您就不必太在意所有类型的性能和“正确”行为,可以使用此来使某些东西起作用所有类型的数组,而不仅仅是数字

a = np.array(['a', 'b', None])
b = np.array(['a', 'b', None])
assert list(a) == list(b)

ndarray投射到list s 有时对于在某些测试中获得所需的行为很有用。 (但是请不要在生产代码或更大的数组中使用它!)

答案 7 :(得分:0)

numpy函数array_equal非常适合问题的要求。当被问到时,它很可能不存在。 该示例如下所示:

a = np.array([1, 2, np.NaN])
b = np.array([1, 2, np.NaN])
assert np.array_equal(a, b, equal_nan=True)

答案 8 :(得分:0)

v1.9 开始,numpy 的 array_equal 函数支持 equal_nan 参数:

assert np.array_equal(a, b, equal_nan=True)

答案 9 :(得分:0)

对我来说这很好用:

a = numpy.array(float('nan'), 1, 2)
b = numpy.array(2, float('nan'), 2)
numpy.equal(a, b, where = 
    numpy.logical_not(numpy.logical_or(
        numpy.isnan(a), 
        numpy.isnan(b)
    ))
).all()

附注。有 nan 时忽略比较