Мы можем использовать np.lib.stride_tricks.as_strided
на основе scikit-image's view_as_windows
, чтобы получить скользящие оконные представления в NaNs
дополненной версии ввода, и представление будет эффективным для памяти ипроизводительность.
Реализация будет выглядеть примерно так -
from skimage.util.shape import view_as_windows
def sliding_windows_grouped(a, W, fillval = np.nan):
# W : Number of rows to be grouped for each row in output array
m,n = a.shape
ext = np.full((W-1)*n, fillval)
a_ext = np.concatenate((a[::-1].ravel(),ext))
return view_as_windows(a_ext,n*W,step=n)[::-1]
Дополнительная информация по использованию as_strided
на основе view_as_windows
.
Запуски Samnple -
In [63]: a
Out[63]:
array([[55, 58],
[75, 78],
[78, 20],
[94, 32],
[47, 98]])
In [64]: sliding_windows_grouped(a, W=2)
Out[64]:
array([[55., 58., nan, nan],
[75., 78., 55., 58.],
[78., 20., 75., 78.],
[94., 32., 78., 20.],
[47., 98., 94., 32.]])
In [65]: sliding_windows_grouped(a, W=3)
Out[65]:
array([[55., 58., nan, nan, nan, nan],
[75., 78., 55., 58., nan, nan],
[78., 20., 75., 78., 55., 58.],
[94., 32., 78., 20., 75., 78.],
[47., 98., 94., 32., 78., 20.]])
In [66]: sliding_windows_grouped(a, W=4)
Out[66]:
array([[55., 58., nan, nan, nan, nan, nan, nan],
[75., 78., 55., 58., nan, nan, nan, nan],
[78., 20., 75., 78., 55., 58., nan, nan],
[94., 32., 78., 20., 75., 78., 55., 58.],
[47., 98., 94., 32., 78., 20., 75., 78.]])
Предельное улучшение
Мы можем пропустить окончательное переключение на последнем шаге из решения, предложенного ранее с использованием np.lib.stride_tricks.as_strided
, например, -
def sliding_windows_grouped_v2(a, W, fillval = np.nan):
# W : Number of rows to be grouped for each row in output array
m,n = a.shape
ext = np.full((W-1)*n, fillval)
a_ext = np.concatenate((a[::-1].ravel(),ext))
strided = np.lib.stride_tricks.as_strided
s = a_ext.strides[0]
return strided(a_ext[(m-1)*n:],strides=(-n*s,s), shape=(m,W*n))