在Numpy中,找到两个数组中每对元素之间的欧几里得距离

4

我有两组二维坐标点的数组(x,y)

a = [ (x1,y1), (x2,y2), ... (xN,yN) ]
b = [ (X1,Y1), (X2,Y2), ... (XN,YN) ]

如何在一个1xN数组中找到每个对齐的点(xi,yi)到(Xi,Yi)之间的欧几里得距离?

scipy.spatial.cdist函数可以给出NxN数组中所有一对对的距离。

如果我只是使用norm函数逐个计算距离,似乎速度会很慢。

是否有内置的函数可以做到这一点?

3个回答

10

我没有看到内置的选项,但你可以很容易地自己完成它。

distances = (a-b)**2
distances = distances.sum(axis=-1)
distances = np.sqrt(distances)

1
虽然结果相同,但使用np.dot进行平方和加法更快:delta = a-b; dist = np.dot(delta, delta); dist = np.sqrt(dist) - Jaime
我认为 dot 不会像那样向量化; 它计算二维输入的矩阵乘积。你可能可以用 einsum 做些什么,但我不知道爱因斯坦求和约定,所以很难用它给出答案。 - user2357112
2
糟糕!您绝对是正确的,它是 inner1dimport numpy.core.umath_tests as ut; delta = a-b; dist = np.sqrt(dnp.inner1d(delta, delta))。或者 dist = np.sqrt(np.einsum('ij, ij->i', delta, delta)) - Jaime

2

hypot是另一种有效的选择。

a, b = randn(10, 2), randn(10, 2)
ahat, bhat = (a - b).T
r = hypot(ahat, bhat)

timeit 测试手动计算和 hypot 的结果:

手动计算:

timeit sqrt(((a - b) ** 2).sum(-1))
100000 loops, best of 3: 10.3 µs per loop

使用 hypot:
timeit hypot(ahat, bhat)
1000000 loops, best of 3: 1.3 µs per loop

现在我们来看一些成人尺寸的数组:
a, b = randn(1e7, 2), randn(1e7, 2)
ahat, bhat = (a - b).T

timeit -r10 -n3 hypot(ahat, bhat)
3 loops, best of 10: 208 ms per loop

timeit -r10 -n3 sqrt(((a - b) ** 2).sum(-1))
3 loops, best of 10: 224 ms per loop

这两种方法之间的性能差异不大。通过避免使用pow,您可以从后者中挤出更多微小的性能提升。

d = a - b

timeit -r10 -n3 sqrt((d * d).sum(-1))
3 loops, best of 10: 184 ms per loop

0

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