在滑动窗口中求元素之和 - NumPy

12

有没有一种numpy的方式可以在区间内每三个元素进行求和?例如:

import numpy as np
mydata = np.array([4, 2, 3, 8, -6, 10])

我希望获得这个结果:

np.array([9, 13, 5, 12])

1
@Ohumeronen 解释“conv”可能需要一些时间。但是在帖子中添加了一些相关的注释。 - Divakar
非常感谢您抽出时间。我看到这个函数似乎相当复杂,但我也会阅读一些相关文档。再次感谢! - Ohumeronen
可能是如何使用NumPy计算移动平均值?的重复问题。 - Trevor Boyd Smith
可能是重复的 https://dev59.com/g2Yr5IYBdhLWcg3wYZKD - Trevor Boyd Smith
3个回答

27
我们可以使用np.convolve -
np.convolve(mydata,np.ones(3,dtype=int),'valid')

卷积的基本思想是,我们有一个核,我们将其滑动通过输入数组,并且卷积操作将内核元素乘以元素之和加起来,当内核滑过时。因此,为了解决窗口大小为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')的输出。现在一切都清楚了 :-) - Ohumeronen

9

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]])

2
一种不使用外部库的解决方案可能如下所示:
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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接