1

我有一个x,y,z点列表。使用下式找出在3-dPython中三维点之间的最小距离,平均距离和最大距离

import math 
import numpy as np 

point0 = x0, y0, z0 
point1 = x1, y1, z1 

dist = math.sqrt((x0-x1)**2+(y0-y1)**2+(z0-z1)**2) 

def dist3d((x0, y0, z0), (x1, y1, z1)): 
    return math.sqrt((x0-x1)**2+(y0-y1)**2+(z0-z1)**2) 

两个点之间的距离我希望写一个优化的循环和存储的距离

点= [(472765.09,6191522.78,13.0),(472764.82, 6191524.09,9.0),(472763.8,6191525.68,8.0),(472764.07,6191524.39,16.0)]

dist01 = dist3d(test[0],test[1]) 
dist02 = dist3d(test[0],test[2]) 
dist03 = dist3d(test[0],test[2]) 
dist04 = dist3d(test[0],test[2]) 

dist12 = dist3d(test[1],test[2]) 
dist13 = dist3d(test[1],test[3]) 

dist23 = dist3d(test[2],test[3]) 

3d_l=[(dist01),(dist02),(dist03),(dist04),(dist12),(dist13),(dist23)] 

3d_max =max(3d_l) 
3d_min = min(3d_l) 
3d_mean = np.average(3d_l) 

我写下面的函数(它不是最佳的)

def dist3d((x0, y0, z0), (x1, y1, z1)): 
    return math.sqrt((x0-x1)**2+(y0-y1)**2+(z0-z1)**2) 

def dist_3d(obs): 
    dist_list = list() 
    while len(obs) != 1: 
     obs_g = [(obs[0], x) for x in obs[1:]] 
     dist_list.append([dist3d(obs_g[i][0], obs_g[i][1]) for i in xrange(len(obs_g))]) 
     obs.pop(0) 
    return dist_list 

points = [(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)] 
print dist_3d(points) 
[[4.217700795331081, 5.922339064664832, 3.554222840244929], [2.1374049685457694, 7.046453008421205], [8.107835716151763]] 
+0

什么是你的问题? –

+0

伊夫感谢您的重播。我的问题是将这些代码行转换为(高效)循环 –

+0

是的,但是它不能做什么?这样的(双)循环是微不足道的。顺便说一句,你想要的平均数或中位数?这会造成很大的差异。 –

回答

2

如果你不介意使用SciPy的,这是相当简单:

import numpy as np 
import scipy.spatial.distance as distance 

points = np.array([(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)]) 

dist = distance.pdist(points) 
print dist.max() 
print dist.min() 
print np.median(dist) 
print np.average(dist) 
-1

math.sqrt是一个比较繁重的操作。你可以存储距离的平方,这足以找到最小值,中值和最大值,然后得到平方根。此外,尝试手动查找单次迭代的最大值和最小值。

+1

不适用于“meadian”:) –

+0

@YvesDaoust我很困惑,为什么它不能用于中位数。列表的中间位置仍然是列表的中间位置,无论您是获得正方形还是平方根,只要您一致。虽然我并不是说这个答案是正确的,但是你的评论(以及我正在进行的投票)并不是真的一致,因为他提供了一个关于简化循环的思考过程,并且它在技术上回答了这个问题be-it,not well) –

+0

中位数应该是一样的是,平均值不会。而且我不确定哪个OP需要。他在文中说中位数,但在代码中使用平均值。标题中的 – M4rtini

1

这是一个通用版本,尽可能使用内置和模块函数。我没有安装numpy,但如果它具有3-D或n-D距离功能,请使用下面的代替dist3D()

实际上,numpy包含几个(其他)函数可用于加速这些即时计算中的一些。如果你正在寻找更多基于它的答案,你应该至少通过修改你问题的标签来表明这一点。

import math 
import numpy as np 

points = [(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), 
      (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)] 
points += [points[0]] # dup first point to include dist from last to first 
dist3D = lambda a, b: math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2 + (a[2]-b[2])**2) 
dists = sorted(dist3D(points[i], points[i+1]) for i in xrange(len(points)-1)) 
min_dist, max_dist = dists[0], dists[-1] 
#mean_dist = sum(dists)/len(dists) 
mean_dist = np.average(dists) 

print 'min_dist: {:.2f}, mean_dist: {:.2f}, max_dist: {:.2f}'.format(
    min_dist, mean_dist, max_dist)