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