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:
import time
import numpy as np
arr1 = np.random.uniform(size=1000000)
arr2 = np.array([0.1, 0.2, 0.3, 0.35, 0.5, 0.4, 0.38, 0.2, 0.15])
result = np.zeros(len(arr1))
start_time = time.time()
for i in range(0, len(arr1) - len(arr2)):
for j in range (0, len(arr2)):
result[i+j] += arr1[i] * arr2[j]
print("--- %s seconds ---" % (time.time() - start_time))
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.
result = np.convolve(arr1, arr2)[:len(arr1)]
diff = len(arr1) - len(arr2)
for k in range(diff, len(arr1)):
# i = k - j
# 0 <= i < diff gives k - diff < j <= k
# 0 <= j < len(arr2)
lo = max(0, 1 + k - diff)
hi = min(1 + k, len(arr2))
result[k] = np.dot(arr1[k-hi+1:k-lo+1][::-1], arr2[lo:hi])