Summing elements in a sliding window - NumPy

We can use np.convolve -

np.convolve(mydata,np.ones(3,dtype=int),'valid')

The basic idea with convolution is that we have a kernel that we slide through the input array and the convolution operation sums the elements multiplied by the kernel elements as the kernel slides through. So, to solve our case for a window size of 3, we are using a kernel of three 1s generated with np.ones(3).

Sample run -

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

A solution without using external libraries might look like this:

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)

Which gives the output:

[1, 2, 3, 3, 4, 4, 3, 2, 3, 2, 1, 1, 1, 0, 0, 1]

This matches the result of using numpy:

import numpy as np
np.convolve(v, np.ones(5, dtype=int),'valid').tolist()

Starting in Numpy 1.20, the sliding_window_view provides a way to slide/roll through windows of elements. Windows that you can then individually sum:

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

where:

  • window_shape is the size of the sliding window
  • np.sum(array, axis = 1) sums sub-arrays

and the intermediate result of the sliding is:

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

Tags:

Python

Numpy