在三维空间中有两个点

a = (ax, ay, az)
b = (bx, by, bz)

我想计算它们之间的距离:

dist = sqrt((ax-bx)^2 + (ay-by)^2 + (az-bz)^2)

我如何用NumPy做到这一点?我有:

import numpy
a = numpy.array((ax, ay, az))
b = numpy.array((bx, by, bz))

当前回答

从Python 3.8开始

从Python 3.8开始,数学模块包含了math.dist()函数。 请看这里https://docs.python.org/3.8/library/math.html#math.dist。

数学。dist (p1, p2) 返回两点p1和p2之间的欧氏距离, 每一个都以坐标序列(或可迭代对象)给出。

import math
print( math.dist( (0,0),   (1,1)   )) # sqrt(2) -> 1.4142
print( math.dist( (0,0,0), (1,1,1) )) # sqrt(3) -> 1.7321

其他回答

用NumPy或一般的Python做这件事的最好方法是什么?我有:

最好的方法是最安全的,也是最快的

我建议使用低流量来获得可靠的结果,因为与编写自己的平方根计算器相比,下溢和溢出的几率非常小

我们来看看数学。函数,np。Hypot vs vanilla np.sqrt(np.sum(np.数组([i, j, k])) ** 2,轴=1))

i, j, k = 1e+200, 1e+200, 1e+200
math.hypot(i, j, k)
# 1.7320508075688773e+200
np.sqrt(np.sum((np.array([i, j, k])) ** 2))
# RuntimeWarning: overflow encountered in square

速度智慧的数学。Hypot看起来更好

%%timeit
math.hypot(i, j, k)
# 100 ns ± 1.05 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%%timeit
np.sqrt(np.sum((np.array([i, j, k])) ** 2))
# 6.41 µs ± 33.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

下溢

i, j = 1e-200, 1e-200
np.sqrt(i**2+j**2)
# 0.0

溢出

i, j = 1e+200, 1e+200
np.sqrt(i**2+j**2)
# inf

没有下溢

i, j = 1e-200, 1e-200
np.hypot(i, j)
# 1.414213562373095e-200

没有溢出

i, j = 1e+200, 1e+200
np.hypot(i, j)
# 1.414213562373095e+200

请参考

这个公式很容易用

distance = np.sqrt(np.sum(np.square(a-b)))

它实际上只是使用毕达哥拉斯定理来计算距离,通过将Δx, Δy和Δz的平方相加,并对结果进行根运算。

使用scipy.spatial.distance.euclidean:

from scipy.spatial import distance
a = (1, 2, 3)
b = (4, 5, 6)
dst = distance.euclidean(a, b)

从Python 3.8开始,math模块直接提供dist函数,它返回两点之间的欧几里得距离(以元组或坐标列表的形式给出):

from math import dist

dist((1, 2, 6), (-2, 3, 2)) # 5.0990195135927845

如果你使用列表:

dist([1, 2, 6], [-2, 3, 2]) # 5.0990195135927845

一个很好的句子:

dist = numpy.linalg.norm(a-b)

但是,如果速度是一个问题,我建议在您的机器上进行试验。我发现,在我的机器上,使用数学库的√rt和**运算符对平方进行运算要比使用一行NumPy解决方案快得多。

我用这个简单的程序进行了测试:

#!/usr/bin/python
import math
import numpy
from random import uniform

def fastest_calc_dist(p1,p2):
    return math.sqrt((p2[0] - p1[0]) ** 2 +
                     (p2[1] - p1[1]) ** 2 +
                     (p2[2] - p1[2]) ** 2)

def math_calc_dist(p1,p2):
    return math.sqrt(math.pow((p2[0] - p1[0]), 2) +
                     math.pow((p2[1] - p1[1]), 2) +
                     math.pow((p2[2] - p1[2]), 2))

def numpy_calc_dist(p1,p2):
    return numpy.linalg.norm(numpy.array(p1)-numpy.array(p2))

TOTAL_LOCATIONS = 1000

p1 = dict()
p2 = dict()
for i in range(0, TOTAL_LOCATIONS):
    p1[i] = (uniform(0,1000),uniform(0,1000),uniform(0,1000))
    p2[i] = (uniform(0,1000),uniform(0,1000),uniform(0,1000))

total_dist = 0
for i in range(0, TOTAL_LOCATIONS):
    for j in range(0, TOTAL_LOCATIONS):
        dist = fastest_calc_dist(p1[i], p2[j]) #change this line for testing
        total_dist += dist

print total_dist

在我的机器上,math_calc_dist运行得比numpy_calc_dist快得多:1.5秒对23.5秒。

为了在fastst_calc_dist和math_calc_dist之间获得一个可测量的差异,我必须将TOTAL_LOCATIONS增加到6000。然后,fastst_calc_dist耗时约50秒,math_calc_dist耗时约60秒。

您也可以尝试使用numpy。SQRT和numpy。不过这两个运算都比我机器上的数学运算要慢。

我的测试使用Python 2.6.6运行。