2017-01-26 13 views
1

私はサイズが50x50x4の3D numpy配列を持っています。私は50x50平面上のいくつかの点の位置も持っています。各点について、ポイントを中心に11x11x4の領域を抽出する必要があります。境界が重なる場合、この領域はラップアラウンドする必要があります。これを行う最も効率的な方法は何ですか?3D numpy配列から複数のパッチを選択する

私は現在、forループを使用して各ポイントを繰り返し、3Dマトリックスをサブセット化し、初期化前の配列に格納しています。これを行うnumpy関数が組み込まれていますか?ありがとうございました。


遅い応答のため、申し訳ありませんが、皆様のご意見ありがとうございます。

答えて

1

をスライスすることができます最後の軸に沿ってnp.padwrappingの機能を使用します。次に、このパッディングされたバージョンのスライディングウィンドウをnp.lib.stride_tricks.as_stridedで作成します。パディングされた配列のビューはメモリをもう使用しません。最後に、最終出力を得るためにスライディングウィンドウにインデックスを作成します。

# Based on http://stackoverflow.com/a/41850409/3293881 
def patchify(img, patch_shape): 
    X, Y, a = img.shape 
    x, y = patch_shape 
    shape = (X - x + 1, Y - y + 1, x, y, a) 
    X_str, Y_str, a_str = img.strides 
    strides = (X_str, Y_str, X_str, Y_str, a_str) 
    return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides) 

def sliding_patches(a, BSZ): 
    hBSZ = (BSZ-1)//2 
    a_ext = np.dstack(np.pad(a[...,i], hBSZ, 'wrap') for i in range(a.shape[2])) 
    return patchify(a_ext, (BSZ,BSZ)) 

サンプル実行 -

In [51]: a = np.random.randint(0,9,(4,5,2)) # Input array 

In [52]: a[...,0] 
Out[52]: 
array([[2, 7, 5, 1, 0], 
     [4, 1, 2, 0, 7], 
     [1, 3, 0, 8, 4], 
     [8, 0, 5, 2, 7]]) 

In [53]: a[...,1] 
Out[53]: 
array([[0, 3, 3, 8, 7], 
     [3, 8, 2, 8, 2], 
     [8, 4, 3, 8, 7], 
     [6, 6, 8, 5, 5]]) 

それでは、aで1つの中心点を選択してみましょう、のは(1,0)を言うと、その周りにblocksize (BSZ) = 3のパッチを入手してみましょう -

In [54]: out = sliding_patches(a, BSZ=3) # Create sliding windows 

In [55]: out[1,0,...,0] # patch centered at (1,0) for slice-0 
Out[55]: 
array([[0, 2, 7], 
     [7, 4, 1], 
     [4, 1, 3]]) 

In [56]: out[1,0,...,1] # patch centered at (1,0) for slice-1 
Out[56]: 
array([[7, 0, 3], 
     [2, 3, 8], 
     [7, 8, 4]]) 

ので、 (1,0)周辺のパッチを得る最終出力は、単にout[1,0,...,:]、すなわちout[1,0]となります。

のは、とにかく、オリジナル形状のアレイ上の形状チェックをしてみましょう -

In [65]: a = np.random.randint(0,9,(50,50,4)) 

In [66]: out = sliding_patches(a, BSZ=11) 

In [67]: out[1,0].shape 
Out[67]: (11, 11, 4) 
0

パッドにあなたの元の配列になりますどのように多くの時間あなたはこの1簡単かつ効率的な方法をしなければならない依存:

p = np.concatenate([a[-5:, ...], a, a[:5, ...]], axis=0) 
p = np.concatenate([p[:, -5:, :], p, p[:, :5, :]], axis=1) 

その後、あなたは、単に一つのアプローチは次のようになり

s = p[x0 : x0 + 11, x1 : x1 + 11, :] 
関連する問題