2016-05-29 67 views
5

我有大約100,000個二維數組,我需要應用本地過濾器。兩個尺寸的尺寸都是一樣的,而且窗口已經超過了2×2的尺寸,並進一步移動了2個,這樣每個元素都會在窗口中顯示一次。輸出是一個相同大小的二進制二維數組,我的過濾器也是一個二進制2×2塊。我的過濾器的0部分將映射到0,我的過濾器部分是1全部映射到1,如果它們具有相同的值,並且映射到0,如果它們不完全相同。這裏有一個例子:在移動窗口numpy數組上有效地應用函數

Filter: 0 1  Array to filter: 1 2 3 2 Output: 0 1 0 0 
     1 0      2 3 3 3    1 0 0 0 

我當然可以使用雙for循環做然而,這是非常低效的,並必須有一個更好的辦法。我讀到這個:Vectorized moving window on 2D array in numpy但是我不確定我會如何將它應用於我的案例。

回答

4

您可以拆分每個2x2子陣列,然後重新塑形,使每個加窗塊成爲2D陣列中的一行。 從每一行中,使用boolean indexing提取出對應於f==1職位的元素。 然後,看看是否所有提取的元素沿着每一行是相同的,給我們一個面具。重塑後,使用此掩碼與f乘以最終的二進制輸出。

因此,假設f作爲濾波器陣列和A作爲數據陣列,量化執行遵循這樣的步驟是這樣的 -

# Setup size parameters 
M = A.shape[0] 
Mh = M/2 
N = A.shape[1]/2 

# Reshape input array to 4D such that the last two axes represent the 
# windowed block at each iteration of the intended operation  
A4D = A.reshape(-1,2,N,2).swapaxes(1,2) 

# Determine the binary array whether all elements mapped against 1 
# in the filter array are the same elements or not 
S = (np.diff(A4D.reshape(-1,4)[:,f.ravel()==1],1)==0).all(1) 

# Finally multiply the binary array with f to get desired binary output 
out = (S.reshape(Mh,N)[:,None,:,None]*f[:,None,:]).reshape(M,-1) 

樣品運行 -

1)輸入:

In [58]: A 
Out[58]: 
array([[1, 1, 1, 1, 2, 1], 
     [1, 1, 3, 1, 2, 2], 
     [1, 3, 3, 3, 2, 3], 
     [3, 3, 3, 3, 3, 1]]) 

In [59]: f 
Out[59]: 
array([[0, 1], 
     [1, 1]]) 

2)中間體輸出:

In [60]: A4D 
Out[60]: 
array([[[[1, 1], 
     [1, 1]], 

     [[1, 1], 
     [3, 1]], 

     [[2, 1], 
     [2, 2]]], 


     [[[1, 3], 
     [3, 3]], 

     [[3, 3], 
     [3, 3]], 

     [[2, 3], 
     [3, 1]]]]) 

In [61]: S 
Out[61]: array([ True, False, False, True, True, False], dtype=bool) 

3)最終輸出:

In [62]: out 
Out[62]: 
array([[0, 1, 0, 0, 0, 0], 
     [1, 1, 0, 0, 0, 0], 
     [0, 1, 0, 1, 0, 0], 
     [1, 1, 1, 1, 0, 0]]) 
+0

相同的方法可以用做'np.kron(〜np.any(np.diff(A4D [...,F == 1]), -1),f)';-) – 2016-05-30 09:22:31

+0

@morningsun啊是在最後一步乘法的'kron'!謝謝! – Divakar