2017-04-09 115 views
1

在我的腳本中,我需要比較相當大的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本身有一些內置函數?

+0

生產樣品數據? – Divakar

+0

是的。 如果單元格不相等 - 我想獲取單元格的座標和兩個數組中的值。 – Nissim

回答

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))) 

的打印的二維數組表示哪個切片的滿足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)擁有所有這些信息。