我需要有效地计算将一个数组的元素乘以第二个数组的所有元素的运行总和。解释我想用代码做什么可能是最简单的:
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))
我的 'a' 数组通常很大,所以我希望它尽可能快地运行,但现在它太慢了(在我的电脑上大约 5 秒)。在 Python 中是否有更有效的方法?
答案 0 :(得分:1)
通常将两个滑动窗口相乘称为convolution,在numpy中实现。您的定义最后略有不同,但是可以修复。
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])
答案 1 :(得分:0)
你的 result[i+j] 符号让我困惑了一秒钟,但这样做的方法相当简单。滑动乘法只不过是一个一维的concolution,它方便地包含在numpy中 最后的 len(arr2) 值不同,但应该很容易处理。 编辑:orlp 处理了它
np.convolve(arr1,arr2)[:-len(arr2)]
--- 0.003989458084106445 秒 ---