[英]Calculate euclidean distance with numpy
我有一個點集,我將它的坐標存儲在三個不同的數組(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 實現嗎?
一個不同的解決方案是使用 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]))
您可以使用np.subtract.outer(xa, xb)
計算每個 xa 到每個 xb 的差異。 到最近的 xb 的距離由下式給出
np.min(np.abs(np.subtract.outer(xa, xb)), axis=1)
要將其擴展到 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)
如果您真的想知道哪個b 點最近,您可以使用argmin
代替min
。
index_of_nearest = np.argmin(distances, axis=1)
有不止一種方法可以做到這一點。 最重要的是,內存使用和速度之間存在權衡。 這是浪費的方法:
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
的點集,以避免擴展到完整的矩陣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.