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