如何将每行之间的 np.linalg.norm 向量化为矩阵

how to Vectorize the np.linalg.norm between to matices for each row

我正在尝试优化我的代码和以下示例数组(长度可以是动态的):

arr1 = np.random.random(300).reshape((-1,3))
arr2 = np.random.random(450).reshape((-1,3))

>>> arr1 

array([[0.32725109, 0.39912246, 0.9834273 ],
        [0.78003681, 0.92057381, 0.06478441],
        [0.15232456, 0.82258548, 0.1685084 ],
        ...
        [0.10011657, 0.05840116, 0.07685251],
        [0.360477  , 0.09061205, 0.54737966],
        [0.44562439, 0.90453774, 0.27240101]])

以下代码是关键部分:

result_arr = np.zeros((arr1.shape[0],arr2.shape[0]))
for arr1_index,arr1_row in enumerate(arr1):
    for arr2_index, arr2_row in enumerate(arr2):
        result_arr[arr1_index,arr2_index] = 1/(1+np.linalg.norm(arr1_row - arr2_row,2) ** (1/3) )

并且性能太差,我是否知道如何将此 np.linalg.norm 函数转换为矢量化方式并跳过循环的使用。这里还有算术要考虑,我可以解决吗?

您可以使用广播并利用 linalg.norm 函数的矢量化特性,在一个函数调用中执行如下操作(在我的计算机中,这实现了 2 个数量级的速度改进):

import numpy as np
# Create dummy arrays
arr1 = np.random.random(300).reshape((-1,3))
arr2 = np.random.random(450).reshape((-1,3))
# Output
r = 1 / (1 + np.linalg.norm(arr1[:,None] - arr2, axis=-1)**(1/3))

我怀疑可以通过 NumPy 的 einsum 函数获得进一步的改进。