在三维空间中有两个点
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))
在三维空间中有两个点
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))
当前回答
用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
请参考
其他回答
我喜欢np。点(点积):
a = numpy.array((xa,ya,za))
b = numpy.array((xb,yb,zb))
distance = (np.dot(a-b,a-b))**.5
我在matplotlib中找到了一个“dist”函数。mlab,但我认为它不够方便。
我把它贴在这里只是为了参考。
import numpy as np
import matplotlib as plt
a = np.array([1, 2, 3])
b = np.array([2, 3, 4])
# Distance between a and b
dis = plt.mlab.dist(a, b)
import numpy as np
# any two python array as two points
a = [0, 0]
b = [3, 4]
首先将list更改为numpy数组,并像这样做:print(np.linalg.norm(np.array(a) - np.array(b)))。第二种方法直接从python列表as: print(np.linalg.norm(np.subtract(a,b)))
对于那些对一次计算多个距离感兴趣的人来说,我已经使用perfplot(我的一个小项目)做了一些比较。
第一个建议是组织数据,使数组具有维数(3,n)(显然是c连续的)。如果加法发生在连续的第一维中,事情会更快,如果你使用带有axis=0的sqrt-sum, linalg,它也不会太重要。轴=0的范数,或
a_min_b = a - b
numpy.sqrt(numpy.einsum('ij,ij->j', a_min_b, a_min_b))
这是,以微弱优势,最快的变种。(这实际上也只适用于一行。)
在第二个轴上求和的变量,轴=1,都要慢得多。
代码重现情节:
import numpy
import perfplot
from scipy.spatial import distance
def linalg_norm(data):
a, b = data[0]
return numpy.linalg.norm(a - b, axis=1)
def linalg_norm_T(data):
a, b = data[1]
return numpy.linalg.norm(a - b, axis=0)
def sqrt_sum(data):
a, b = data[0]
return numpy.sqrt(numpy.sum((a - b) ** 2, axis=1))
def sqrt_sum_T(data):
a, b = data[1]
return numpy.sqrt(numpy.sum((a - b) ** 2, axis=0))
def scipy_distance(data):
a, b = data[0]
return list(map(distance.euclidean, a, b))
def sqrt_einsum(data):
a, b = data[0]
a_min_b = a - b
return numpy.sqrt(numpy.einsum("ij,ij->i", a_min_b, a_min_b))
def sqrt_einsum_T(data):
a, b = data[1]
a_min_b = a - b
return numpy.sqrt(numpy.einsum("ij,ij->j", a_min_b, a_min_b))
def setup(n):
a = numpy.random.rand(n, 3)
b = numpy.random.rand(n, 3)
out0 = numpy.array([a, b])
out1 = numpy.array([a.T, b.T])
return out0, out1
b = perfplot.bench(
setup=setup,
n_range=[2 ** k for k in range(22)],
kernels=[
linalg_norm,
linalg_norm_T,
scipy_distance,
sqrt_sum,
sqrt_sum_T,
sqrt_einsum,
sqrt_einsum_T,
],
xlabel="len(x), len(y)",
)
b.save("norm.png")
计算多维空间的欧氏距离:
import math
x = [1, 2, 6]
y = [-2, 3, 2]
dist = math.sqrt(sum([(xi-yi)**2 for xi,yi in zip(x, y)]))
5.0990195135927845