我有 2 个点列表作为 numpy.ndarray,每一行都是一个点的坐标,例如:
a = np.array([[1,0,0],[0,1,0],[0,0,1]])
b = np.array([[1,1,0],[0,1,1],[1,0,1]])
Run Code Online (Sandbox Code Playgroud)
这里我想计算2个列表中所有点对之间的欧氏距离,对于a中的每个点p_a,我想计算它与b中每个点p_b之间的距离。所以结果是
d = np.array([[1,sqrt(3),1],[1,1,sqrt(3)],[sqrt(3),1,1]])
Run Code Online (Sandbox Code Playgroud)
如何使用numpy中的矩阵乘法来计算距离矩阵?
jak*_*vdp 11
使用直接 numpy 广播,您可以执行以下操作:
dist = np.sqrt(((a[:, None] - b[:, :, None]) ** 2).sum(0))
Run Code Online (Sandbox Code Playgroud)
或者,scipy有一个例程可以更有效地计算这个问题(特别是对于大型矩阵)
from scipy.spatial.distance import cdist
dist = cdist(a, b)
Run Code Online (Sandbox Code Playgroud)
我会避免依赖于分解矩阵乘积(形式为 A^2 + B^2 - 2AB)的解决方案,因为它们可能由于浮点舍入误差而在数值上不稳定。
为了计算每对元素 x 和 y 的欧氏距离平方,我们需要找到:
(Xik-Yjk)**2 = Xik**2 + Yjk**2 - 2*Xik*Yjk
Run Code Online (Sandbox Code Playgroud)
然后沿k求和得到对应点的距离dist(Xi,Yj)。
使用关联性,它可以简化为:
dist(Xi,Yj) = sum_k(Xik**2) + sum_k(Yjk**2) - 2*sum_k(Xik*Yjk)
Run Code Online (Sandbox Code Playgroud)
在最后一部分引入矩阵乘法,我们将得到所有距离,如下所示 -
dist = sum_rows(X^2), sum_rows(Y^2), -2*matrix_multiplication(X, Y.T)
Run Code Online (Sandbox Code Playgroud)
因此,用 NumPy 术语来说,我们最终会得到以a和b作为输入的情况的欧几里德距离,如下所示 -
np.sqrt((a**2).sum(1)[:,None] + (b**2).sum(1) - 2*a.dot(b.T))
Run Code Online (Sandbox Code Playgroud)
利用np.einsum,我们可以将前两个求和约简替换为 -
np.einsum('ij,ij->i',a,a)[:,None] + np.einsum('ij,ij->i',b,b)
Run Code Online (Sandbox Code Playgroud)
eucl_dist 更多信息可以在包上找到wiki page(免责声明:我是它的作者)。
| 归档时间: |
|
| 查看次数: |
13815 次 |
| 最近记录: |