在滑动窗口中求和元素 - NumPy
Posted
技术标签:
【中文标题】在滑动窗口中求和元素 - NumPy【英文标题】:Summing elements in a sliding window - NumPy 【发布时间】:2016-11-25 05:58:55 【问题描述】:有一种 numpy 方法可以对区间中的每个三个元素求和吗?例如:
import numpy as np
mydata = np.array([4, 2, 3, 8, -6, 10])
我想得到这个结果:
np.array([9, 13, 5, 12])
【问题讨论】:
@Ohumeronen 解释conv
可能需要一段时间。但在帖子中添加了一些相关的 cmets。
哦,非常感谢您抽出宝贵的时间。我看到这个函数似乎很复杂,但我也会阅读一些关于它的文档。再次感谢!
How to calculate moving average using NumPy?的可能重复
***.com/q/13728392/52074的可能重复
【参考方案1】:
我们可以使用np.convolve
-
np.convolve(mydata,np.ones(3,dtype=int),'valid')
convolution
的基本思想是我们有一个内核,我们在输入数组中滑动,当内核滑动通过时,卷积运算将元素乘以内核元素相加。因此,为了解决我们的窗口大小为3
的情况,我们使用由np.ones(3)
生成的三个1s
的内核。
示例运行 -
In [334]: mydata
Out[334]: array([ 4, 2, 3, 8, -6, 10])
In [335]: np.convolve(mydata,np.ones(3,dtype=int),'valid')
Out[335]: array([ 9, 13, 5, 12])
【讨论】:
啊现在我明白了。根据提供的数据,我使用 np.convolve(mydata,[1,2],'valid') 进行了尝试,但不明白为什么结果不是 [8,8,19,-4,14]。但这是 np.convolve(mydata,[2,1],'valid') 的输出。现在一切都清楚了:-)【参考方案2】:从Numpy 1.20
开始,sliding_window_view
提供了一种在元素窗口中滑动/滚动的方式。然后可以单独求和的窗口:
from numpy.lib.stride_tricks import sliding_window_view
# values = np.array([4, 2, 3, 8, -6, 10])
np.sum(sliding_window_view(values, window_shape = 3), axis = 1)
# array([9, 13, 5, 12])
地点:
window_shape
是滑动窗口的大小
np.sum(array, axis = 1)
对子数组求和
而滑动的中间结果是:
sliding_window_view(np.array([4, 2, 3, 8, -6, 10]), window_shape = 3)
# array([[ 4, 2, 3],
# [ 2, 3, 8],
# [ 3, 8, -6],
# [ 8, -6, 10]])
【讨论】:
【参考方案3】:不使用外部库的解决方案可能如下所示:
from collections import deque
def sliding_window_sum(a, size):
out = []
the_sum = 0
q = deque()
for i in a:
if len(q)==size:
the_sum -= q[0]
q.popleft()
q.append(i)
the_sum += i
if len(q)==size:
out.append(the_sum)
return out
v = [0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]
sliding_window_sum(v, 5)
它给出了输出:
[1, 2, 3, 3, 4, 4, 3, 2, 3, 2, 1, 1, 1, 0, 0, 1]
这与使用 numpy 的结果相匹配:
import numpy as np
np.convolve(v, np.ones(5, dtype=int),'valid').tolist()
【讨论】:
以上是关于在滑动窗口中求和元素 - NumPy的主要内容,如果未能解决你的问题,请参考以下文章
如何创建一个与 numpy 数组重叠 50% 的滑动窗口? [复制]
LeetCode 1658 将x减到0的最小操作数前缀和 滑动窗口 HERODING的LeetCode之路