有一个漂亮的把戏与stride_tricks
,你可以找到在滚动不同一般性窗口功能,以便和其他(当前有没有在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()
)。
编辑:既然slices
阵列是2D的,而不是3D的,因为你追加,一个重塑缺少这里:
slices = diagonal.reshape(-1,2)
,如果你有这样的小数组这可能不是快,但它的常数(期待数据复制diagonal
调用)与数组大小。
切片是否必须是方形的? – Bitwise
@Bitwise“任意(但类似)成型2D切片”,所以,不一定是正方形 – goncalopp