【问题标题】:In Numpy, find Euclidean distance between each pair from two arrays在 Numpy 中,从两个数组中找到每对之间的欧几里得距离
【发布时间】:2013-07-29 23:36:42
【问题描述】:

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

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

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

scipy.spatial.cdist 函数给出了NxN 数组中所有对之间的距离。

如果我只是使用norm函数一一计算距离,它似乎很慢。

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

【问题讨论】:

    标签: python arrays numpy scipy euclidean-distance


    【解决方案1】:

    我没有看到内置的,但你可以很容易地自己做。

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

    【讨论】:

    • np.dot:delta = a-b; dist = np.dot(delta, delta); dist = np.sqrt(dist)进行平方和加法速度是一样的
    • 我不认为dot 那样矢量化;它计算二维输入的矩阵乘积。你可能可以用einsum 做点什么,但我不知道爱因斯坦求和约定,所以我很难用它给出答案。
    • 糟糕!你是绝对正确的,是inner1d 做到了:import 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)).
    【解决方案2】:

    hypot 是另一个有效的替代方案

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

    手动计算和hypot之间timeits的结果:

    手册:

    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
    

    【讨论】:

      猜你喜欢
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 2020-06-10
      • 2019-06-19
      • 2016-02-15
      • 2010-12-24
      相关资源
      最近更新 更多