将NumPy数组与阈值进行比较并返回差异

时间:2017-04-09 13:40:54

标签: python arrays python-3.x numpy

在我的脚本中,我需要比较相当大的NumPy数组(2D或3D)和阈值。 比较本身可以通过" allclose"轻松完成。功能,就像那样:

Threshold = 0.1
if (np.allclose(Arr1, Arr2, Threshold, equal_nan=True)):
    Print('Same')

知道哪些单元格不相同的最简单(但又天真)的方法是使用像这样的简单for循环代码:

def CheckWhichCellsAreNotEqualInArrays(Arr1,Arr2,Threshold):
   if not Arr1.shape == Arr2.shape:
       return ['Arrays size not the same']
   Dimensions = Arr1.shape  
   Diff = []
   for i in range(Dimensions [0]):
       for j in range(Dimensions [1]):
           if not np.allclose(Arr1[i][j], Arr2[i][j], Threshold, equal_nan=True):
               Diff.append(',' + str(i) + ',' + str(j) + ',' + str(Arr1[i,j]) + ',' 
               + str(Arr2[i,j]) + ',' + str(Threshold) + ',Fail\n')
       return Diff

(对于3D阵列也是如此 - 还有1个用于循环)

当阵列很大并且充满了不相等的单元时,这种方式非常慢。

是否有快速直接的方式以防它们不相同 - 获得不均匀细胞的列表?也许是NumPy本身的一些内置函数?

1 个答案:

答案 0 :(得分:0)

函数allclose相当于allisclose的组合。因此,您可以将isclose应用于整个数组,然后根据需要将all应用于某些轴,而不是循环遍历数组的某些维。 (至关重要的是,all采用轴参数而allclose没有)。具有4D随机数据阵列的示例,其中正在比较一些2D切片。

threshold = 0.1
arr1 = 10 + np.random.normal(size=((40, 30, 20, 10)))
arr2 = arr1 + 0.3 * np.random.normal(size=((40, 30, 20, 10)))
print(np.all(np.isclose(arr1, arr2, threshold), axis=(2, 3)))

打印一个2D数组,显示哪个切片满足allclose条件:

array([[False,  True,  True, ...,  True,  True, False],
       [ True, False,  True, ...,  True,  True, False],
       [False,  True,  True, ..., False,  True,  True],
       ..., 
       [False, False,  True, ...,  True,  True,  True],
       [ True,  True,  True, ..., False,  True,  True],
       [ True, False,  True, ...,  True, False, False]], dtype=bool)

也就是说,arr1[0, 0]arr2[0, 0]并不接近;但是arr1[0, 1]arr2[0, 1]是。如有必要,您可以深入查看元素级别,以找出close条件的确切失败; np.isclose(arr1, arr2, threshold)拥有所有这些信息。