2017-04-18 8 views
6

私は要素がTrueまたはFalseの値で多次元numpyの配列があります。今、私は別の配列Mを生成する必要がチェックPythonの

import numpy as np 
#just making a toy array grid to show what I want to do 
grid = np.ones((4,4),dtype = 'bool') 
grid[0,0]=False 
grid[-1,-1]=False 
#now grid has a few false values but is a 4x4 filled with mostly true values 

を、各サイトM [I、J]の値がグリッドに依存

M = np.empty((4x4)) #elements to be filled 

#here is the part I want to clean up 
for ii in range(4): 
    for jj in range(4): 

     #details here are unimportant. It's just that M[ii,jj] depends on 
     #multiple elements of grid in some way 
     if ii+2<=4 and jj+2<=4:  
      M[ii,jj] = np.all(grid[ii:ii+2,jj:jj+2]==True) 
     else: 
      M[ii,jj] = False 

のように[I:I + 2、J J + 2]グリッドからの要素を使用してアレイMを満たすためにいくつかの方法はありますダブルループなしで?

答えて

3

アプローチ#1

ここ2D convolutionと一つのアプローチだ -

from scipy.signal import convolve2d as conv2 

out = (conv2(grid,np.ones((2,2),dtype=int),'valid')==4).astype(int) 

サンプル実行 -

In [118]: grid 
Out[118]: 
array([[False, True, True, True], 
     [ True, True, True, True], 
     [ True, True, True, True], 
     [ True, True, True, False]], dtype=bool) 

In [119]: (conv2(grid,np.ones((2,2),dtype=int),'valid')==4).astype(int) 
Out[119]: 
array([[0, 1, 1], 
     [1, 1, 1], 
     [1, 1, 0]]) 

が期待される出力からの最後の行と最後の列は、ということに注意してください初期化された出力配列ですべて0になります。これは、行と列に沿った程度がそれほど大きくないため、コードの滑りやすい性質のためです。

アプローチ#2

ここ2D均一なフィルタを有する別の -

from skimage.util import view_as_windows as viewW 

out = viewW(grid,(2,2)).all(axis=(2,3)).astype(int) 
012 - 4D slided windowed view有する別ここ

from scipy.ndimage.filters import uniform_filter as unif2d 

out = unif2d(grid,size=2).astype(int)[1:,1:] 

アプローチ#3

です

all(axis=(2,3))とすると、すべての要素のすべてのウィンドウの寸法が両方ともTrueの要素になるようにチェックしています。


ランタイムテスト

In [122]: grid = np.random.rand(5000,5000)>0.1 

In [123]: %timeit (conv2(grid,np.ones((2,2),dtype=int),'valid')==4).astype(int) 
1 loops, best of 3: 520 ms per loop 

In [124]: %timeit unif2d(grid,size=2).astype(int)[1:,1:] 
1 loops, best of 3: 210 ms per loop 

In [125]: %timeit viewW(grid,(2,2)).all(axis=(2,3)).astype(int) 
1 loops, best of 3: 614 ms per loop 
+0

おかげDivakar!私はスライディングされたウィンドウビューが私にとって最も理にかなっていると思います。そのアプローチはこのプロジェクトの後半で他のタスクにも役立つはずです。私は彼らがどのように動作するかを理解するためにこれらをもう少し調べなければなりません – kevinkayaks

+0

私はviewW(グリッド、(2,2))がグリッドから2x2ブロックを引き出すことを理解しています。 簡単な質問の入力:.all((2,3))は何をするのですか?なぜ(2,3)? – kevinkayaks

+0

@kevinkayaksコメントが少ない。 – Divakar

関連する問題