numpy.lib.stride_tricks.as_strided 结果类型转换和随机值

numpy.lib.stride_tricks.as_strided resulting typecasts and random values

我正在使用 np.lib.stride_tricks.as_strided 生成滑动 windows 使用以下

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 一切正常,我得到以下结果,这是出乎意料的,因为:

即使我使用

将结果转换回 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]]])

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 填充它,我会在那些额外的插槽中获得 'random' 值。这部分为什么 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]])

现在您可以 select 每第 n 行,没有任何有趣的值(浮点数 nan 除外)。

所以as_strided需要适当的步幅、适当的形状和适当的填充。