2016-05-29 7 views
5

私はローカルフィルタを適用する必要がある約100,000の2次元配列を持っています。両方のディメンションは偶数のサイズを持ち、ウィンドウは2x2個以上あり、さらに2個ずつシフトして、すべての要素が一度ウィンドウに表示されるようにします。出力は同じサイズのバイナリ2次元配列で、私のフィルタはバイナリ2x2の部分でもあります。ゼロであるフィルタの部分は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 [...、== 1 F])、 -1)、f) ';-) –

+0

@morningsunああ、最後のステップでの乗算のための' kron'!ありがとう! – Divakar

関連する問題