には気の利いたトリックがあり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
呼び出し中のデータのコピーを期待) は配列のサイズによって異なります。