2014-02-18 97 views
2

一個列表中給出一個點查找最接近值:在字典鍵的Python的

 a=[X,Y,Z] 

我基本上是試圖從字典列表找到最近的3點到指定點。

的數據類型,它需要比較的形式給出的simplifed例如:

 points=[{'Point':1,'co-ordinate':[0,1,2]},{'Point':2',co-ordinate':[0,1,3]},{'Point':3,'co-ordinate':[1,1,2]}] etc. 

任何意見或建議?

+0

您可以使用具有預測功能的SVM內核http://scikit-learn.org/stable/modules/svm.html。每一個「協調」都可以定義爲一個多分類任務; a = [[X],[Y],[Z]]/[X,Y,Z]和clf.predict。 – user1749431

+0

您發現哪一部分問題最困難? 「python實現或算法問題的」給定一個輸入點x找到列表中最接近的點?「這是爲了瞭解您是否需要關於如何操作Python的列表和字典的建議。 –

+1

鑑於這樣的物理問題,我可以解決它但是,這並不意味着我可以用Python編寫它,我仍然是一個新手!我只需要一點關於Python實現和操作複雜列表/字典的指導。 – Juiceboxbandit

回答

0

您可以保留一個反向查找表,您可以在其中返回鍵值對並將座標存儲爲鍵。這很容易實現。然後您可以再次返回鍵並在每個座標上執行距離公式。

如你所知,距離公式爲:

dist = sqrt((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2) 

注:看起來你有在該列表中3個不同的字典。

+0

我看到簡單!謝謝JFA。 – Juiceboxbandit

0

最近的意味着你定義了一個距離函數。對於太空中的一個點,norm 2 is usually used。我們首先編寫一個計算兩點之間規範的函數,但是因爲我們可能必須將它用於迭代器(或者可能是因爲我預見到了某些關鍵函數),所以我們將它作爲closure(以找到最接近的價值,那很酷)。現在

from math import sqrt 

def norm2(ptA): 
    def norm2_close(ptB): 
     xA, yA, zA = ptA 
     xB, yB, zb = ptB 
     return sqrt((xA-xB)**2 + (yA-yB)**2 + (zA-zB)**2) 
    return norm2_close 

,我們可以做

>>> normFromA = norm2([1, 2, 3]) 
>>> normFromA([3, 2, 1]) 
2.8284271247461903 
>>> normfromA([4, 5, 6]) 
5.196152422706632 

很好。但是我們仍然需要從你的清單中得到最小的。有很多可能性,但作爲我們寫了一個漂亮的關閉,我們只是修改,以適合我們的需要:

def norm2InDict(ptA): 
    def norm2InDict_close(dict_for_ptB): 
     xA, yA, zA = ptA 
     xB, yB, zB = dict_for_ptB['co-ordinate'] 
     return sqrt((xA-xB)**2 + (yA-yB)**2 + (zA-zB)**2) 
    return norm2InDict_close 

,讓蟒蛇做boring work

>>> min(points, key=norm2InDict([1, 2, 3])) 
{'co-ordinate': [0, 1, 3], 'Point': 2} 

要了解的功能,Python會循環通過列表(每個字典)的元素,在其上應用關鍵函數(這將計算範數2),比較關鍵字並返回具有最小關鍵字的元素。對。如果我想要三個最接近的元素,而不是一個?那麼,文檔告訴我們,我們可以使用該heapq模塊(我的一些點添加到列表中,更多的樂趣):

>>> import heapq 
>>> points=[ 
    {'Point':1,'co-ordinate':[0,1,2]}, 
    {'Point':2,'co-ordinate':[0,1,3]}, 
    {'Point':3,'co-ordinate':[1,1,2]}, 
    {'Point':4,'co-ordinate':[2,5,2]}, 
    {'Point':5,'co-ordinate':[1,0,2]}, 
    {'Point':6,'co-ordinate':[1,2,2]} 
] 
>>> heapq.nsmallest(3, points, key=norm2InDict([1, 2, 3])) 
[{'co-ordinate': [1, 2, 2], 'Point': 6}, {'co-ordinate': [0, 1, 3], 'Point': 2}, {'co-ordinate': [1, 1, 2], 'Point': 3}] 
0

你可以排序的點基於距離函數列表,然後使用第一。

import math 
a=[0,0,0] 

def dist(p0,p1): 
    return math.sqrt((p1[0]-p0[0])**2+(p1[1]-p0[1])**2+(p1[2]-p0[2])**2) 

points=[{'Point':1,'co-ordinate':[0,1,2]},{'Point':2,'co-ordinate':[0,1,3]},{'Point':3,'co-ordinate':[1,1,2]},] 

sorted_by_dist = sorted(points,key=lambda p:dist(a,p['co-ordinate'])) 
closest = sorted_by_dist[0] 
furthest = sorted_by_dist[-1] 
0

瞭解sorted函數==>https://wiki.python.org/moin/HowTo/Sorting。我認爲要尋找的是sorted函數中的key選項。

一旦你知道了排序後的函數,你可以對你的字典和鍵進行排序,只需提供排序功能即可。因此,讓我們說,你有一點p作爲

p = [2,3,4] # or any other list value ... 

然後一個函數,這點與另一併返回一個dictance可以寫成:

# Note that there s no need for the Numpy dependency. I do this only for 
# brevety. You can use the dist function which was previously mentioned. 
import numpy as np 
def dist(p1, p2): 
    p1, p2 = np.array(p1), np.array(p2) 
    return sqrt(sum((p1 - p2)**2)) 

現在你只需排序陣列,並將前3個點取爲:

pointList = sorted(points, key = lambda x: dist(x['co-ordinate'], p) )[:3]