4

2次元配列があり、その中のセクション(スライス)を新しい配列に抽出する必要があります。

original= numpy.ndarray( shape=(4,4) )
slices= numpy.ndarray( shape=(0,2) )
for x in range(3):
    slice= original[x:x+2,x:x+2] 
    slices=numpy.append(slices, slice,axis=0)

これを行うためのより効率的な方法はありますか(サイクルのためにPythonを取り除く)?

- - 編集 - -

明確にするために、2D配列の任意の2Dインデックスから別の垂直に積み重ねられた(特に対角線に沿っていない、または2x2サイズの)任意の(ただし同様の)形状の2Dスライスをコピーする方法を尋ねています。

4

2 に答える 2

3

には気の利いたトリックがありstride_tricks、SO とその他で異なる一般性を持つローリング ウィンドウ関数を見つけることができます (現在、numpy 自体には何もありません)。

def rolling_window(arr, window):
    """Very basic multi dimensional rolling window. window should be the shape of
    of the desired subarrays. Window is either a scalar or a tuple of same size
    as `arr.shape`.
    """
    shape = np.array(arr.shape*2)
    strides = np.array(arr.strides*2)
    window = np.asarray(window)
    shape[arr.ndim:] = window # new dimensions size
    shape[:arr.ndim] -= window - 1
    if np.any(shape < 1):
        raise ValueError('window size is too large')
    return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)

# Now:
view = rolling_window(arr, 2)
view[0,0] # first slice in your loop

view元の配列と同じデータを保持していることに注意してください! これにより、予期しない結果が生じる可能性があります。しかし、対角線のみが必要なようです。必要に応じてデータをコピーしないようにするために、ストライド トリックを使用してそれを行うこともできます (次のバージョンでは でビューが作成されdiagonal、古いバージョンでは常にコピーが作成されます)。

diagonal = np.diagonal(view, axis1=0, axis2=1)
# unfortunatly now the first slice is diagonal[...,0], so just roll it to the start:
diagonal = np.rollaxis(diagonal, -1)

diagonalこれが for ループで作成した配列です (新しいバージョンでは.copy()、ビューが必要ない場合は a を追加します) 。

編集:slices追加するため、配列は2Dで3Dではないため、ここでは形状変更がありませんでした:

slices = diagonal.reshape(-1,2)

このような小さな配列がある場合、これは高速ではないかもしれませんが、その定数 (diagonal呼び出し中のデータのコピーを期待) は配列のサイズによって異なります。

于 2012-10-14T09:13:57.040 に答える
1

これがあなたの解決策です:

v = np.arange(0,original.shape[0],0.5).astype(int)
result = np.c_[ original[v[1:-1],v[:-2]] , original[v[1:-1],v[2:]] ]

正方形の入力行列の任意のサイズで機能します(あなたが呼んだ「オリジナル」)。

アイデアは、単に[0,0,1,1,2,2,3,3,...]である「ヘルパー配列」vを作成し、必要なインデックスが常に単純であるという観察を使用することですv のスライス。

楽しみ!

于 2012-10-14T01:12:33.223 に答える