Подход № 1
Мы можем использовать np.lib.stride_tricks.as_strided
на основе scikit-image's view_as_windows
, чтобы получить скользящие окна. Подробнее об использовании as_strided
на основе view_as_windows
.
from skimage.util.shape import view_as_windows
def create_time_lagged_viewaswindows(X, shift, step):
a_ext = np.r_[X.values,np.zeros(shift-1,dtype=X.dtype)]
windows_ar = view_as_windows(a_ext,shift)[:len(X)-shift+step+1:step].T
return pd.DataFrame(windows_ar)
Бит объяснения: Основная идея заключается в том, что мы дополняем трейлинг-сторону нулямиа затем создать раздвижные окна.Для создания окон мы используем np.lib.stride_tricks.as_strided
или skimage.util.view_as_windows
.
Образцы прогонов -
In [166]: X = pd.Series(range(5))
In [167]: create_time_lagged_viewaswindows(X, shift=4, step=1)
Out[167]:
0 1 2
0 0 1 2
1 1 2 3
2 2 3 4
3 3 4 0
In [168]: create_time_lagged_viewaswindows(X, shift=4, step=2)
Out[168]:
0 1
0 0 2
1 1 3
2 2 4
3 3 0
Подход № 2
Мы также можем использовать np.lib.stride_tricks.as_strided
, что потребовало бы от нас ручной настройки шага и придания ему формы, но мы бы избежали транспонирования, как при предыдущем подходе, и это могло бы стоить дополнительного повышения производительности.Реализация будет выглядеть примерно так:
def create_time_lagged_asstrided(X, shift, step):
a_ext = np.r_[X.values,np.zeros(shift-1,dtype=X.dtype)]
strided = np.lib.stride_tricks.as_strided
s = a_ext.strides[0]
ncols = (len(X)-shift+2*step)//step
windows_ar = strided(a_ext, shape=(shift,ncols), strides=(s,step*s))
return pd.DataFrame(windows_ar)
Синхронизация большого массива -
In [215]: X = pd.Series(range(10000))
# Original solution
In [216]: %timeit creat_time_lagged(X, shift=10, step=5)
1 loop, best of 3: 608 ms per loop
# Approach #1
In [217]: %timeit create_time_lagged_viewaswindows(X, shift=10, step=5)
10000 loops, best of 3: 146 µs per loop
# Approach #2
In [218]: %timeit create_time_lagged_asstrided(X, shift=10, step=5)
10000 loops, best of 3: 104 µs per loop