簡體   English   中英

從列表中選擇最近的一對

[英]Select the closest pair from a list

我有一個列表,舉個例子

[(35.9879845760485, -4.74093235801354), (35.9888687992442, -4.72708076713794),
(35.9889733432982, -4.72758983150694), (35.9915751019521, -4.72772881198689), 
(35.9935223025608, -4.72814213543564), (35.9941433944962, -4.72867416528065), 
(35.9946670576458, -4.72915181755908), (35.995946587966, -4.73005565674077), 
(35.9961479762973, -4.7306870912609), (35.9963563641681, -4.7313535758683), 
(35.9968685892892, -4.73182757975504), (35.9976738530666, -4.73194429867996) ]

coord = (35.9945570576458, -4.73110757975504)

我想選擇壁櫥一雙coordlist

編寫距離函數並使用帶有關鍵參數的內置min函數。

>>> from functools import partial
>>> dist=lambda s,d: (s[0]-d[0])**2+(s[1]-d[1])**2 #a little function which calculates the distance between two coordinates
>>> a=[(35.9879845760485, -4.74093235801354), (35.9888687992442, -4.72708076713794), ..... ]
>>> coord = (35.9945570576458, -4.73110757975504)
>>> min(a, key=partial(dist, coord)) #find the min value using the distance function with coord parameter
(35.9961479762973, -4.7306870912609)

您還可以使用scipy cKDTree ,它允許您在陣列上執行最近鄰搜索。 當點列表很長時,這應該比窮舉搜索更好:

import numpy
from scipy.spatial import cKDTree

data = numpy.array([(35.9879845760485, -4.74093235801354), (35.9888687992442,
-4.72708076713794), (35.9889733432982, -4.72758983150694), (35.9915751019521,
-4.72772881198689), (35.9935223025608, -4.72814213543564), (35.9941433944962,
-4.72867416528065), (35.9946670576458, -4.72915181755908), (35.995946587966,
-4.73005565674077), (35.9961479762973, -4.7306870912609), (35.9963563641681,
-4.7313535758683), (35.9968685892892, -4.73182757975504), (35.9976738530666,
-4.73194429867996) ])

tree = cKDTree(data)
dists, indexes = tree.query(numpy.array([35.9945570576458, -4.73110757975504]), k=3)
for dist, index in zip(dists, indexes):
    print 'distance %f:  %s' % (dist, data[index])

輸出:

distance 0.001646:  [ 35.99614798  -4.73068709]
distance 0.001743:  [ 35.99594659  -4.73005566]
distance 0.001816:  [ 35.99635636  -4.73135358]

如果點列表仍然足夠小,線性搜索應該可以做到:

def dist_sq(a, b): # distance squared (don't need the square root)
  return (a[0] - b[0])**2 + (a[1] - b[1])**2

def find(l, coord):
  return min(l, key=lambda p:dist_sq(coord, p))

l = [(35.9879845760485, -4.74093235801354), (35.9888687992442, -4.72708076713794), (35.9889733432982, -4.72758983150694), (35.9915751019521, -4.72772881198689), (35.9935223025608, -4.72814213543564), (35.9941433944962, -4.72867416528065), (35.9946670576458, -4.72915181755908), (35.995946587966, -4.73005565674077), (35.9961479762973, -4.7306870912609), (35.9963563641681, -4.7313535758683), (35.9968685892892, -4.73182757975504), (35.9976738530666, -4.73194429867996) ]
coord = (35.9945570576458, -4.73110757975504)

print find(l, coord)

使用numpy的相同解決方案:

import numpy as np
l = np.array([(35.9879845760485, -4.74093235801354), (35.9888687992442, -4.72708076713794), (35.9889733432982, -4.72758983150694), (35.9915751019521, -4.72772881198689), (35.9935223025608, -4.72814213543564), (35.9941433944962, -4.72867416528065), (35.9946670576458, -4.72915181755908), (35.995946587966, -4.73005565674077), (35.9961479762973, -4.7306870912609), (35.9963563641681, -4.7313535758683), (35.9968685892892, -4.73182757975504), (35.9976738530666, -4.73194429867996) ])
coord = np.array((35.9945570576458, -4.73110757975504))
print l[np.argmin(np.apply_along_axis(np.linalg.norm, 1, l - coord))]

如果這不可行,我建議你研究更好的算法方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM