I need to efficiently calculate the running sum of multiplying the elements of one array by all the elements of a second array. It is probably easiest to explain what I am trying to do with code:
JavaScript
x
15
15
1
import time
2
import numpy as np
3
4
arr1 = np.random.uniform(size=1000000)
5
arr2 = np.array([0.1, 0.2, 0.3, 0.35, 0.5, 0.4, 0.38, 0.2, 0.15])
6
result = np.zeros(len(arr1))
7
8
start_time = time.time()
9
10
for i in range(0, len(arr1) - len(arr2)):
11
for j in range (0, len(arr2)):
12
result[i+j] += arr1[i] * arr2[j]
13
14
print("--- %s seconds ---" % (time.time() - start_time))
15
My ‘a’ array will typically be big so I would like this to run as fast as possible, but right now it is too slow (~5s on my computer). Is there a more efficient way of doing this in Python?
Advertisement
Answer
In general multiplying two sliding windows is called a convolution, implemented in numpy. Your definition is subtly different at the end, however this can be fixed.
JavaScript
1
10
10
1
result = np.convolve(arr1, arr2)[:len(arr1)]
2
diff = len(arr1) - len(arr2)
3
for k in range(diff, len(arr1)):
4
# i = k - j
5
# 0 <= i < diff gives k - diff < j <= k
6
# 0 <= j < len(arr2)
7
lo = max(0, 1 + k - diff)
8
hi = min(1 + k, len(arr2))
9
result[k] = np.dot(arr1[k-hi+1:k-lo+1][::-1], arr2[lo:hi])
10