2013-03-15 95 views
1

我有一個點集,我將它的座標存儲在三個不同的數組(xa,ya,za)中。現在,我想計算該點集(xa [0],ya [0],za [0]等)的每個點與另一個點集(xb,yb,zb)的所有點之間的歐式距離)並且每次將最小距離存儲在一個新數組中。假設xa.shape =(11,),ya.shape =(11,),za.shape =(11,)。分別地,xb.shape =(13,),yb.shape =(13,),zb.shape =(13,)。我想要做的是每次取一個xa [],ya [],za [],並計算它與xb,yb,zb中所有元素的距離,最後將最小值存儲到xfinal中。形狀=(11,)數組。用numpy計算歐氏距離

你認爲這可能與numpy?

+0

換句話說,對於每個'xa/ya/za',你想計算到'xb/yb/zb'中最近點的距離? – NPE 2013-03-15 15:01:26

+0

是的,如果它會更容易... – GiorgosR 2013-03-15 15:04:59

回答

8

不同的解決方案是使用scipy的空間模塊,特別是KDTree。

該類從一組數據中學習,並可以詢問賦予了新的數據集:

from scipy.spatial import KDTree 
# create some fake data 
x = arange(20) 
y = rand(20) 
z = x**2 
# put them togheter, should have a form [n_points, n_dimension] 
data = np.vstack([x, y, z]).T 
# create the KDTree 
kd = KDTree(data) 

現在,如果你有一個點,你可以問的距離和壁櫥點的索引(或者N最近的點)簡單地通過執行:

kd.query([1, 2, 3]) 
# (1.8650720813822905, 2) 
# your may differs 

,或者給定位置的數組:

#bogus position 
x2 = rand(20)*20 
y2 = rand(20)*20 
z2 = rand(20)*20 
# join them togheter as the input 
data2 = np.vstack([x2, y2, z2]).T 
#query them 
kd.query(data2) 

#(array([ 14.96118553, 9.15924813, 16.08269197, 21.50037074, 
# 18.14665096, 13.81840533, 17.464429 , 13.29368755, 
# 20.22427196, 9.95286671, 5.326888 , 17.00112683, 
#  3.66931946, 20.370496 , 13.4808055 , 11.92078034, 
#  5.58668204, 20.20004206, 5.41354322, 4.25145521]), 
#array([4, 3, 2, 4, 2, 2, 4, 2, 3, 3, 2, 3, 4, 4, 3, 3, 3, 4, 4, 4])) 
+3

大大優於其他答案,你也可以使用更快的cKDTree(新的scipy可能是相同的)。 – seberg 2013-03-15 15:52:36

+0

好的,顯然,這個選項效果更好。然而,最後我不知道這是否會在運行這些腳本的abaqus中運行。你知道我該如何從kd.query中提取最小值的數組?提前致謝。 – GiorgosR 2013-03-15 16:55:42

+0

好吧,我做到了。這並不困難。再次感謝。 – GiorgosR 2013-03-15 17:28:35

1

您可以使用np.subtract.outer(xa, xb)來計算每個xa到每個xb的差異。到最近的XB對應的距離由

np.min(np.abs(np.subtract.outer(xa, xb)), axis=1) 

給這個如果你真的想知道的B點是最近的,您在使用argmin擴展到3D,

distances = np.sqrt(np.subtract.outer(xa, xb)**2 + \ 
    np.subtract.outer(ya, yb)**2 + np.subtract.outer(za, zb)**2) 
distance_to_nearest = np.min(distances, axis=1) 

min的地方。

index_of_nearest = np.argmin(distances, axis=1) 
+0

我先發布了一維案例。這看起來正確嗎? – 2013-03-15 15:17:48

+0

是的,我認爲它有效。看起來非常快。我的陣列很大!因此,我認爲我必須通過獲取每一行並計算其與整個xb,yb,zb的距離來遍歷xa,ya,za長度。我認爲它有效。我會交叉檢查其有效性,我會讓你知道。無論如何非常感謝你! – GiorgosR 2013-03-15 15:31:29

+0

如果您可以使用scipy,請參閱@ EnricoGiampieri的colution。 – 2013-03-15 15:56:15

0

有多種方式做到這一點。最重要的是,在內存使用和速度之間進行權衡。這裏的浪費方法:

s = (1, -1) 
d = min((xa.reshape(s)-xb.reshape(s).T)**2 
    + (ya.reshape(s)-yb.reshape(s).T)**2 
    + (za.reshape(s)-zb.reshape(s).T)**2), axis=0) 

另一種方法將是遍歷在b設置爲避免膨脹到完全成熟的矩陣的點。