簡體   English   中英

在字典鍵列表中查找最接近的值Python

[英]Finding closest values in a list of dictionary keys Python

給定一點:

      a=[X,Y,Z]

我本質上是在嘗試從詞典列表中找到與給定點最接近的3點。

需要比較的數據類型的簡化示例以以下形式給出:

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

有什么想法或建議嗎?

您可以保留一個反向查找表,在該表中返回鍵值對並將坐標存儲為鍵。 這很容易實現。 然后,您可以再次返回鍵,並在每個坐標上計算距離公式。

如您所知,距離公式為:

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

注意:您似乎在該列表中有3個不同的字典。

最接近表示您定義了距離函數。 對於空間點, 通常使用范數2 讓我們先編寫一個代碼,該函數計算兩點之間的范數,但是由於我們可能不得不將其用於迭代器(或者可能是因為我預見到某些東西,它是關鍵函數),因此我們將其設為閉包 (以找到最接近的值,好酷)。

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

並讓python做無聊的工作

>>> 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}]

您可以根據距離函數對點列表進行排序,然后使用第一個。

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]

在此處了解有關sorted函數的信息==> https://wiki.python.org/moin/HowTo/Sorting 我認為尋找是sorted功能中的key選項。

一旦知道排序后的函數,就可以對字典進行排序,並輸入要對其進行排序的鍵。 因此,讓我們說您有點p

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

然后,將要指出這一點和另一個結果並返回命令的函數可以寫成:

# 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))

現在,您可以對數組進行排序,並將前三點取為:

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

暫無
暫無

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

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