在处理滚动窗口时,我以列表理解的方式编写了函数
[np.std(x[i:i+framesize]) for i in range(0, len(x)-framesize, hopsize)])]
最近,我发现了
numpy.lib.stride_tricks.as_strided
并发现它被广泛用于滚动窗口(例如this post),即使它是“隐藏”功能。在this issue中,为什么未记录stride_tricks.as_strided的内容提到
与列表理解或for循环相比,
stride_tricks.as_strided
有什么优势吗?我看了the source code of stride_tricks
,但收获甚微。 最佳答案
从 this post
,我们可以使用strided_app
基本上将滑动 View 获取到数组中,它还允许我们指定hopsize/stepsize。然后,我们只需沿第二个轴使用np.std
进行最终输出,就像这样-
np.std(strided_app(x, framesize, hopsize), axis=1)
sample 运行以进行验证-
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])
作为输入数组的 View ,这些跨步操作必须真正有效。让我们找出答案!
运行时测试
循环方法-
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
回答有关效率的问题,计时应该有助于证明这一点!