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)