多维数组之间欧氏距离的 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。距离。
我有两个 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。距离。