numpy stride_tricks.as_strided vs 滚动的列表理解 window
numpy stride_tricks.as_strided vs list comprehension for rolling window
在处理滚动的时候windows,我的函数是按照列表推导的方式写的
[np.std(x[i:i+framesize]) for i in range(0, len(x)-framesize, hopsize)])]
最近我发现了numpy.lib.stride_tricks.as_strided
,发现它被广泛用于滚动windows(例如,this post),尽管它是一个"hidden"函数。
在this issue中关于为什么stride_tricks.as_strided没有记录,提到
Intentionally! It's dangerous! It was just low-level plumbing to help implement broadcast_arrays().
stride_tricks.as_strided
与列表理解或 for 循环相比有什么优势吗?我看了the source code of stride_tricks
,但收获不大。
从 开始,我们可以使用 strided_app
基本上将滑动视图放入数组中,它还允许我们指定 hopsize/stepsize。然后,我们简单地沿第二个轴使用 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
回答关于效率的问题,时间应该有助于证明这一点!
在处理滚动的时候windows,我的函数是按照列表推导的方式写的
[np.std(x[i:i+framesize]) for i in range(0, len(x)-framesize, hopsize)])]
最近我发现了numpy.lib.stride_tricks.as_strided
,发现它被广泛用于滚动windows(例如,this post),尽管它是一个"hidden"函数。
在this issue中关于为什么stride_tricks.as_strided没有记录,提到
Intentionally! It's dangerous! It was just low-level plumbing to help implement broadcast_arrays().
stride_tricks.as_strided
与列表理解或 for 循环相比有什么优势吗?我看了the source code of stride_tricks
,但收获不大。
从 strided_app
基本上将滑动视图放入数组中,它还允许我们指定 hopsize/stepsize。然后,我们简单地沿第二个轴使用 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
回答关于效率的问题,时间应该有助于证明这一点!