欧几里得距离的矢量化实现

4

我正在尝试计算欧几里得距离的向量化实现(使用内积计算X和Y中每个元素之间的距离)。数据如下:

X = np.random.uniform(low=0, high=1, size=(10000, 5))
Y = np.random.uniform(low=0, high=1, size=(10000, 5))

我所做的是:
euclidean_distances_vectorized = np.array(np.sqrt(np.sum(X**2, axis=1) - 2 * np.dot(X, Y.T) + np.sum(Y**2, axis=1)))

尽管这会输出“一些内容”,但答案是错误的,因为每行仍然包含5个元素。有人知道我做错了什么吗?

scipy.spatial.distance_matrix? - hilberts_drinking_problem
@YakymPirozhenko,你是什么意思? - tavalendo
@feijao scipy有一个函数可以以向量化的方式计算两个数组之间的成对欧几里得距离。 - hilberts_drinking_problem
1个回答

5

如果我理解正确的话,这样做应该可以。

np.linalg.norm(X - Y, axis=1)

或者使用 einsum(沿第一个轴的每个差异对的点积的平方根)

np.sqrt(np.einsum('ij,ij->i...', X - Y, X - Y))

如果您想要所有成对距离,请按如下操作:
from scipy.spatial.distance import cdist

cdist(X, Y)

3
你可以使用 np.sqrt(np.einsum('ij,ij->i...', *2*(X - Y,))) 来避免重复计算 X-Y。该方法将为您提供所需的平方根值,同时确保不会重复计算 X-Y - Paul Panzer
2
此外,np.sqrt(ne.evaluate("(X - Y) ** 2").sum(1)) 使用 numexpr 似乎更快。 - hilberts_drinking_problem
@PaulPanzer 不错的技巧,我之前不知道。语法有点晦涩,不过解释器应该在那里做某种缓存吧? - filippo
大多数情况下,只需创建一个中间变量D = X-Y; np.sqrt ...会更简单,但这种技巧对于lambda和一行代码很有用。关于缓存,我不确定X-Y是否有官方保证始终返回相同的答案或没有副作用,因此我不知道解释器是否可以依赖它。 - Paul Panzer
1
哇,你们太棒了。谢谢。 - tavalendo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接