多维数组之间欧氏距离的 Numpy 运算

Numpy operation for euclidean distance between multidimensional arrays

我有两个 numpy 数组。 'A' 大小为 w,h,2,'B' 大小为 n,2。 换句话说,A 是二维向量的二维数组,而 B 是二维向量的一维数组。 结果我想要的是一个大小为 w、h、n 的数组。最后一个维度是一个 n 维向量,其中每个分量是 A 的相应向量(由前两个维度 w 和 h 表示)与 B 的第 n 个向量之间的欧氏距离。

我知道我可以手动遍历 python 中的 w、h 和 n 并计算每个元素的距离,但我想知道是否有使用 numpy 操作的聪明方法以提高性能。

我发现了一些类似的问题,但不幸的是,所有这些问题都使用相同维度的输入数组。

方法 #1

您可以将 A 重塑为 2D,使用期望二维数组作为输入的 Scipy's cdist,获取欧氏距离,最后重塑回 3D

因此,一个实现将是 -

from scipy.spatial.distance import cdist

out = cdist(A.reshape(-1,2),B).reshape(w,h,-1)

方法 #2

因为归约轴的长度只有 2,我们可以只对输入数组进行切片以节省中间数组的内存,就像这样 -

np.sqrt((A[...,0,None] - B[:,0])**2 + (A[...,1,None] - B[:,1])**2)

关于A[...,0,None]A[...,1,None]的解释:

这样 None 我们只是在 sliced A 的末尾引入了一个新轴。好吧,我们举个小例子-

In [54]: A = np.random.randint(0,9,(4,5,2))

In [55]: A[...,0].shape
Out[55]: (4, 5)

In [56]: A[...,0,None].shape
Out[56]: (4, 5, 1)

In [57]: B = np.random.randint(0,9,(3,2))

In [58]: B[:,0].shape
Out[58]: (3,)

所以,我们有:

A[...,0,None]  : 4 x 5 x 1 
B[:,0]         :         3

本质上是:

A[...,0,None]  : 4 x 5 x 1 
B[:,0]         : 1 x 1 x 3

减法时,单例dimsbroadcasted对应其他参与数组的维度-

A[...,0,None] - B  : 4 x 5 x 3

我们对最后一个轴上的第二个索引重复此操作。我们在平方后将这两个数组相加,最后求平方根以获得最终的 eucl。距离。