【发布时间】:2020-05-25 23:31:51
【问题描述】:
我正在寻找一种“最佳”方法来计算给定向量元素的所有成对乘积。如果向量的大小为N,则输出将是大小为N * (N + 1) // 2 的向量,并包含所有(i, j) 与i <= j 对的x[i] * x[j] 值。简单的计算方法如下:
import numpy as np
def get_pairwise_products_naive(vec: np.ndarray):
k, size = 0, vec.size
output = np.empty(size * (size + 1) // 2)
for i in range(size):
for j in range(i, size):
output[k] = vec[i] * vec[j]
k += 1
return output
需求:
- 尽量减少额外的内存分配/使用:如果可能,直接写入输出缓冲区。
- 使用矢量化 NumPy 例程而不是显式循环。
- 避免额外(不必要的)计算。
我一直在玩诸如outer、triu_indices 和einsum 之类的例程以及一些索引/查看技巧,但一直未能找到适合上述要求的解决方案。
【问题讨论】:
-
"如果可能,直接写入输出缓冲区" 你的意思是实际上你已经分配了一个输出数组,或者它可以被多次重用?在@orlp 的 Numba 版本中,分配输出数组实际上是最耗时的部分,而不是计算本身。 (仅 12.8 毫秒计算,43.7 毫秒计算+分配)在我的系统上。
-
我的意思是我想避免对任何临时数组进行不必要的分配。这意味着唯一的分配将用于输出缓冲区,并且它将被计算结果填充。
-
对不起,我一开始没有看到并行化的可能性。有一些潜力...我会添加一个并行版本。
-
@iheap 发布的解决方案是否适合您?
-
我目前正在使用 Numba 解决方案。如果有人想出一个聪明的仅限 NumPy 的解决方案,我会暂时保留这个问题。如果没有,我会在几天后接受 Numba 解决方案。
标签: python numpy vectorization linear-algebra