0

我正在np.lib.stride_tricks.as_strided 使用以下方法生成滑动窗口

wsize=4
overlap=0
vector=np.array(range(31))
fillval=np.nan

part_to_fill=np.full(wsize - (vector.shape[0] - 1) % wsize - 1,fillval)
a_ext = np.concatenate(( vector,part_to_fill))
n = a_ext.strides[0]
strided = np.lib.stride_tricks.as_strided   
res=strided(a_ext, shape=(vector.shape[0],wsize), strides=(n,n))[[np.arange(0,len(vector),wsize-overlap)],:]  

如果overlap=0一切都好,我得到

array([[[  0.,   1.,   2.,   3.],
        [  4.,   5.,   6.,   7.],
        [  8.,   9.,  10.,  11.],
        ..., 
        [ 20.,  21.,  22.,  23.],
        [ 24.,  25.,  26.,  27.],
        [ 28.,  29.,  30.,  nan]]])

但是,如果overlap=1一切都很好,我得到以下信息,这是出乎意料的,因为:

  • 结果被转换为浮动
  • 包含随机数而不是预期的 nan,例如 -3.25951556e-311

    array([[[  0.00000000e+000,   1.00000000e+000,   2.00000000e+000,
           3.00000000e+000],
        [  3.00000000e+000,   4.00000000e+000,   5.00000000e+000,
           6.00000000e+000],
        [  6.00000000e+000,   7.00000000e+000,   8.00000000e+000,
           9.00000000e+000],
        ..., 
        [  2.40000000e+001,   2.50000000e+001,   2.60000000e+001,
           2.70000000e+001],
        [  2.70000000e+001,   2.80000000e+001,   2.90000000e+001,
           3.00000000e+001],
        [  3.00000000e+001,               nan,   0.00000000e+000,
          -3.25951556e-311]]])
    

即使我将结果转换回 int 使用

res.astype(int)

我得到以下可能更糟的

array([[[          0,           1,           2,           3],
        [          3,           4,           5,           6],
        [          6,           7,           8,           9],
        ..., 
        [         24,          25,          26,          27],
        [         27,          28,          29,          30],
        [         30, -2147483648,           0,           0]]])
4

1 回答 1

3

np.nan是一个浮点数。将其连接到整数数组会产生一个浮点数组。

In [101]: x = np.arange(5)

In [102]: np.concatenate((x, np.full(3, np.nan)))   # x1=...
Out[102]: array([  0.,   1.,   2.,   3.,   4.,  nan,  nan,  nan])

In [106]: n=x1.strides[0]
In [107]: strided(x1, shape=(5,3), strides=(n,n))
Out[107]: 
array([[  0.,   1.,   2.],
       [  1.,   2.,   3.],
       [  2.,   3.,   4.],
       [  3.,   4.,  nan],
       [  4.,  nan,  nan]])

如果我没有用足够的填充它,nan我会在那些额外的插槽中获得“随机”值。这部分为什么as_strided是先进的,并且有潜在的危险。

我不明白你为什么overlap在跨步之后通过索引来应用它。以下是我如何通过调整步幅来进行重叠:

In [110]: strided(x1, shape=(5,3), strides=(2*n,n))
Out[110]: 
array([[  0.00000000e+000,   1.00000000e+000,   2.00000000e+000],
       [  2.00000000e+000,   3.00000000e+000,   4.00000000e+000],
       [  4.00000000e+000,               nan,               nan],
       [              nan,               nan,               nan],
       [              nan,               nan,   2.59784163e-306]])

糟糕,我要求的数组太大(或填充不足):

In [112]: strided(x1, shape=(3,3), strides=(2*n,n))
Out[112]: 
array([[  0.,   1.,   2.],
       [  2.,   3.,   4.],
       [  4.,  nan,  nan]])

您的代码添加了一个nan填充。让我们将其更改为 10(只是一个方便的更大数字)。并在没有索引的情况下计算(以获取所有跨行):

In [123]: res.shape
Out[123]: (31, 4)

In [124]: res
Out[124]: 
array([[  0.,   1.,   2.,   3.],
       [  1.,   2.,   3.,   4.],
       [  2.,   3.,   4.,   5.],
       [  3.,   4.,   5.,   6.],
       ...
       [ 27.,  28.,  29.,  30.],
       [ 28.,  29.,  30.,  nan],
       [ 29.,  30.,  nan,  nan],
       [ 30.,  nan,  nan,  nan]])

现在您可以选择每第 n 行,没有任何有趣的值(除了 float nan)。

因此as_strided需要适当的步幅、适当的形状和适当的填充。

于 2018-01-26T19:22:24.870 回答