[英]Filter a numpy ndarray using another numpy ndarray
我有兩個相同形狀的(15081, 56724, 3, 3)
。 我想做的是如下:
假設我們有第一個數組array1[1, 1, :, :]
的橫截面,如下所示:
[[120, 110, 220],
[ 85, 99, 72],
[197, 80, 75]]
我想將它轉換為 boolean ,每行的最大值為True
, rest 為False
。 在整個數組中,這對應於axis=3
。 所以數組在轉換后看起來像這樣:
[[False, False, True],
[False, True, False],
[ True, False, False]]
現在我想過濾另一個數組array2
,使用這個 boolean 數組得到如下所示的內容。 我只想保留array1
中與True
對應的array2
的那些值,並將 rest 設置為零。
[[ 0, 0, 65],
[ 0, 179, 0],
[125, 0, 0]]
我可以使用循環來做到這一點,但它需要一定的時間(甚至更多)。 我期待類似numpy.where(array1.is_max(axis=3), True, False)
的東西,但是在 python 中沒有像is_max
這樣的 function,除此之外軸 3 被折疊並且我無法使用array1
過濾array2
。
在 numpy 中, is_max
大約為argmax
:
indices = array1.argmax(axis=-1)
而不是面具,這會給你一個線性索引,所以你可以做
array2b = np.zeros_like(array2)
index = np.indices(array2.shape[:-1], sparse=True) + (indices,)
array2b[index] = array1[index]
您可以使用np.take_along_axis
和np.put_along_axis
做類似的事情:
indices = np.expand_dims(array1.argmax(-1), array1.ndim - 1)
array2b = np.zeros_like(array2)
np.put_along_axis(array2b, indices, np.take_along_axis(array2, indices, -1), -1)
如果你想要一個基於掩碼的方法,你可以像這樣創建掩碼:
mask = array1 != array1.max(-1, keepdims=True)
現在您可以直接將所有元素設置為零:
array2[mask] = 0
或者你可以做類似的事情
mask = array1 == array1.max(-1, keepdims=True)
array2 *= mask
更新
根據您在評論中的描述,您正在尋找完全不同的操作。 您可以從對array1
進行閾值處理開始(我假設它代表模糊圖像和原始圖像之間的差異):
mask = array1 >= 100 # find a threshold that works
array2 *= mask
或者
mask = array1 < 100
array2[mask] = 0
您也可能正在尋找圖像中的局部最小值。 您可以通過找到比周圍環境大的像素來獲得這些像素。 為此,對圖像運行非線性過濾器,例如scipy.ndimage.maximum_filter
:
mask = array1 == scipy.ndimage.maximum_filter(array1, 5)
array2 *= mask
可以用
array2[array1 != np.tile(np.max(array1,axis=1), (array1.shape[0],1)).T] = 0
方法如下。
對於您的特定示例,我建議使用np.tile
,您可以在其中使用一維掩碼中的元素創建重復圖案。
假設我們有您的矩陣 a 和值
array1 = [[120, 110, 220]
[85, 99, 72]
[197, 80, 75]]
那么矩陣每一行中的最大值將是
maxes = np.max(array1,axis=1)
這將具有值
array([220, 99, 197])
現在,我們需要的是在每個行元素的每一行中使用這些值中的每一個。 簡單來說,我們需要將220與第一行的每個元素進行比較。 這意味着實際上我們需要重復值 220,以便能夠在單個向量中執行操作,這可以通過以下方式完成:
np.tile(maxes, (array1.shape[0],1)).T
這給了我們
array([[220, 220, 220],
[ 99, 99, 99],
[197, 197, 197]])
過濾非常簡單:
a != np.tile(maxes, (3,1)).T
足以創建面具。
長話短說,操作可以在單個襯墊中完成,如下所示:
array2[array1 != np.tile(maxes, (a.shape[0],1)).T] = 0
這使 a 具有以下值
array2 = array([[0, 0, 65]
[0, 179, 0]
[125, 0, 0]])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.