考虑一个维度为NxM的numpy数组A。目标是计算欧几里得距离矩阵D,其中每个元素D[i,j]是第i行和第j行之间的欧几里得距离。最快的方法是什么?这并不是我需要解决的问题,但这是一个很好的例子,说明我想要做的事情(通常,可以使用其他距离度量)。
到目前为止,这是我能想到的最快方法:
到目前为止,这是我能想到的最快方法:
n = A.shape[0]
D = np.empty((n,n))
for i in range(n):
D[i] = np.sqrt(np.square(A-A[i]).sum(1))
但这是最快的方法吗?我主要关心for循环。我们能用Cython之类的工具击败它吗?
为了避免循环,我尝试使用广播,并进行以下操作:
D = np.sqrt(np.square(A[np.newaxis,:,:]-A[:,np.newaxis,:]).sum(2))
但是事实证明这是一个不好的想法,因为构建一个中间的三维数组NxNxM会有一些开销,所以性能会更差。
我尝试了Cython。但我在Cython方面是新手,所以我不知道我的尝试有多好:
def dist(np.ndarray[np.int32_t, ndim=2] A):
cdef int n = A.shape[0]
cdef np.ndarray[np.float64_t, ndim=2] dm = np.empty((n,n), dtype=np.float64)
cdef int i = 0
for i in range(n):
dm[i] = np.sqrt(np.square(A-A[i]).sum(1)).astype(np.float64)
return dm
上面的代码比Python的for循环慢了一些。我不太了解Cython,但我认为我至少可以达到与for循环+numpy相同的性能。我想知道在正确的方式下是否有可能实现一些显著的性能提升?或者是否有其他方法可以加速(不涉及并行计算)?