6

在处理滚动窗口时,我以列表理解之类的方式编写函数

[np.std(x[i:i+framesize]) for i in range(0, len(x)-framesize, hopsize)])]

最近我发现numpy.lib.stride_tricks.as_strided它被广泛用于滚动窗口(例如,this post),即使它是一个“隐藏”功能。

这个关于为什么 stride_tricks.as_strided 没有记录的问题中,提到了

故意地!这很危险!它只是帮助实现broadcast_arrays() 的低级管道。

stride_tricks.as_strided与列表理解或 for 循环相比有什么优势吗?我看了一下源代码,stride_tricks但收获甚少。

4

1 回答 1

3

this post,我们可以使用 strided_app基本上将滑动视图放入数组中,它还允许我们指定跳数/步长。然后,我们简单地np.std沿第二个轴使用最终输出,就像这样 -

np.std(strided_app(x, framesize, hopsize), axis=1)

样品运行验证 -

In [162]: x = np.random.randint(0,9,(11))

In [163]: framesize = 5

In [164]: hopsize = 3

In [165]: np.array([np.std(x[i:i+framesize]) \
            for i in range(0, len(x)-framesize+1, hopsize)])
Out[165]: array([ 1.62480768,  2.05912603,  1.78885438])

In [166]: np.std(strided_app(x, framesize, hopsize), axis=1)
Out[166]: array([ 1.62480768,  2.05912603,  1.78885438])

作为输入数组的视图,这些跨步操作必须非常有效。让我们找出来!

运行时测试

循环方法 -

def loopy_app(x, framesize, hopsize):
    return [np.std(x[i:i+framesize]) \
        for i in range(0, len(x)-framesize+1, hopsize)]

计时 -

In [185]: x = np.random.randint(0,9,(1001))

In [186]: framesize = 5

In [187]: hopsize = 3

In [188]: %timeit loopy_app(x, framesize, hopsize)
10 loops, best of 3: 17.8 ms per loop

In [189]: %timeit np.std(strided_app(x, framesize, hopsize), axis=1)
10000 loops, best of 3: 111 µs per loop

所以,要回答关于效率的问题strides,时间应该有助于证明这一点!

于 2017-01-07T12:28:11.207 回答