将NumPy数组与阈值进行比较并返回差异
问题描述:
在我的脚本中,我需要比较相当大的NumPy数组(2D或3D)和阈值。 的比较本身可以做很容易与“allclose”功能,这样做:将NumPy数组与阈值进行比较并返回差异
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更for循环)
这种方式是非常缓慢的,当阵列是大和全没有相等的细胞。
如果他们不一样 - 是否有一个快速直接的方式 - 获取不均匀细胞的列表?也许NumPy本身有一些内置函数?
答
功能allclose
相当于all
和isclose
的组合。因此,您可以将整个数组应用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)))
的打印的二维数组表示哪个切片的满足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)
拥有所有这些信息。
生产样品数据? – Divakar
是的。 如果单元格不相等 - 我想获取单元格的坐标和两个数组中的值。 – Nissim