There is a numpy way to make a sum each three elements in the interval? For example:
import numpy as np
mydata = np.array([4, 2, 3, 8, -6, 10])
I would like to get this result:
np.array([9, 13, 5, 12])
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])
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]])
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.