我们可以使用NumPy使其 深奥地 进入那些滑动窗口中
strided tricks。如果您将此新尺寸用于矩阵乘法之类的约简,那将是理想的选择。如果出于某种原因想要
2D输出,则需要在最后使用重塑,但这将导致创建副本。
因此,实现看起来像这样-
from numpy.lib.stride_tricks import as_strided as strideddef get_sliding_window(df, W, return2D=0): a = df.values s0,s1 = a.strides m,n = a.shape out = strided(a,shape=(m-W+1,W,n),strides=(s0,s0,s1)) if return2D==1: return out.reshape(a.shape[0]-W+1,-1) else: return out
2D / 3D输出的样品运行-
In [68]: dfOut[68]: A B0 0.44 0.411 0.46 0.472 0.46 0.023 0.85 0.824 0.78 0.76In [70]: get_sliding_window(df, 3,return2D=1)Out[70]: array([[ 0.44, 0.41, 0.46, 0.47, 0.46, 0.02], [ 0.46, 0.47, 0.46, 0.02, 0.85, 0.82], [ 0.46, 0.02, 0.85, 0.82, 0.78, 0.76]])
这是3D视图输出的样子-
In [69]: get_sliding_window(df, 3,return2D=0)Out[69]: array([[[ 0.44, 0.41], [ 0.46, 0.47], [ 0.46, 0.02]], [[ 0.46, 0.47], [ 0.46, 0.02], [ 0.85, 0.82]], [[ 0.46, 0.02], [ 0.85, 0.82], [ 0.78, 0.76]]])
我们将其计时以
3D输出各种窗口大小的视图-
In [331]: df = pd.Dataframe(np.random.rand(1000, 3).round(2))In [332]: %timeit get_3d_shfted_array(df,2) # @Yakym Pirozhenko's soln10000 loops, best of 3: 47.9 µs per loopIn [333]: %timeit get_sliding_window(df,2)10000 loops, best of 3: 39.2 µs per loopIn [334]: %timeit get_3d_shfted_array(df,5) # @Yakym Pirozhenko's soln10000 loops, best of 3: 89.9 µs per loopIn [335]: %timeit get_sliding_window(df,5)10000 loops, best of 3: 39.4 µs per loopIn [336]: %timeit get_3d_shfted_array(df,15) # @Yakym Pirozhenko's soln1000 loops, best of 3: 258 µs per loopIn [337]: %timeit get_sliding_window(df,15)10000 loops, best of 3: 38.8 µs per loop
让我们验证一下我们确实在获取视图-
In [338]: np.may_share_memory(get_sliding_window(df,2), df.values)Out[338]: True
get_sliding_window甚至跨各种窗口大小的几乎恒定的时间表明获取视图而不是复制具有巨大的好处。



