我写了一个函数(在SO的帮助下(一个函数,从系列a
中提取具有重叠L
的滑动窗口,当L/(L-overlap(不是整数时,在右侧或左侧填充fillval
,使用numpy步幅:
def strided_axis0_overlap(a, fillval, L,overlap,pad='left'): # a is 1D array
assert(overlap<L)
if pad=='left':
a_ext = np.concatenate(( np.full(L-1,fillval) ,a))
elif pad=='right':
a_ext = np.concatenate((a,np.full(L-1,fillval)))
n = a_ext.strides[0]
strided = np.lib.stride_tricks.as_strided
if pad=='left':
return strided(a_ext, shape=(a.shape[0],L), strides=(n,n))[[np.arange(0,len(a),L-overlap)],:]
elif pad=='right':
return strided(a_ext, shape=(a.shape[0],L), strides=(n,n))[[np.arange(0,len(a),L-overlap)],:]
它工作正常,除了填充。如果我这样做
v=np.array(range(182)).T
strided_axis0_overlap(v,np.nan,5*6,0,pad='right')
我得到以下预期
:array([[[ 0., 1., 2., ..., 27., 28., 29.],
[ 30., 31., 32., ..., 57., 58., 59.],
[ 60., 61., 62., ..., 87., 88., 89.],
...,
[ 120., 121., 122., ..., 147., 148., 149.],
[ 150., 151., 152., ..., 177., 178., 179.],
[ 180., 181., nan, ..., nan, nan, nan]]])
但是,如果我在左侧垫
array([[[ nan, nan, nan, ..., nan, nan, 0.],
[ 1., 2., 3., ..., 28., 29., 30.],
[ 31., 32., 33., ..., 58., 59., 60.],
...,
[ 91., 92., 93., ..., 118., 119., 120.],
[ 121., 122., 123., ..., 148., 149., 150.],
[ 151., 152., 153., ..., 178., 179., 180.]]])
而我希望最后一个窗口以 182 完成,第一个是这样的 array([[[ nan, nan, ..., nan, 0, 1.],
你总是填充L - 1
元素。这在必须的情况下太多了,但在右填充的情况下,这并不重要,因为数组末尾的多余元素将被忽略。但是,在左填充的情况下,这是值得注意的,因为所有元素从一开始就在数组中结束。
在特定情况下,您插入 29 个元素,但您只需要 28 个,因此数组中的最后一项将从滑动窗口中删除。
要插入的元素数应取决于数组大小和窗口大小,如下所示:
L - (a.shape[0] - 1) % L - 1
这将计算为使数组大小成为窗口大小的整数倍所需的元素数(如果它们已经匹配,则可以为 0(。