简体   繁体   English

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

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

Given a point: 给定一点:

      a=[X,Y,Z]

I am essentially trying to find the closest 3 points to that given point from a list of dictionaries. 我本质上是在尝试从词典列表中找到与给定点最接近的3点。

A simplifed example of the kind of data it needs to compare to is given in the form: 需要比较的数据类型的简化示例以以下形式给出:

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

Any ideas or suggestions? 有什么想法或建议吗?

You can keep a reverse lookup table, where you return the key-value pairs and store the coordinates as the key. 您可以保留一个反向查找表,在该表中返回键值对并将坐标存储为键。 This is easy to implement. 这很容易实现。 Then you can return the keys again and do the distance formula on each coordinate. 然后,您可以再次返回键,并在每个坐标上计算距离公式。

As you know, the distance formula is: 如您所知,距离公式为:

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

Note: It looks like you have 3 different dictionaries in that list. 注意:您似乎在该列表中有3个不同的字典。

Closest implies that you define a distance function. 最接近表示您定义了距离函数。 For a point in space, the norm 2 is usually used . 对于空间点, 通常使用范数2 Let's code first a function that computes that norm between two points, but as we will probably have to use it against an iterator (or maybe because I foresee something, as a key function) we make it a closure (to find the closest value, that cool). 让我们先编写一个代码,该函数计算两点之间的范数,但是由于我们可能不得不将其用于迭代器(或者可能是因为我预见到某些东西,它是关键函数),因此我们将其设为闭包 (以找到最接近的值,好酷)。

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

Now, we can do 现在,我们可以做

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

Very well. 很好。 But we still need to get the minimum from your list of dicts. 但是,我们仍然需要从您的词典列表中获取最少的内容。 There are many possibilities, but as we wrote a nice closure, let's just modify it to suit our needs: 有很多可能性,但是当我们编写了一个不错的闭包时,让我们对其进行修改以适合我们的需求:

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

and let python do the boring work 并让python做无聊的工作

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

To understand the function, python will loop through the elements of the lists (each dictionary), apply the key function on them (that will compute the norm 2), compare the keys and return the element that has the smallest key. 为了理解该函数,python将遍历列表的元素(每个字典),将键函数应用于它们(将计算范数2),比较键并返回具有最小键的元素。 Right. 对。 And if I want the three closest elements, and not a single one? 如果我要三个最接近的元素,而不是一个? Well, the documentation tells us we can use the heapq module for that (I add some points to the list, for more fun): 好了,文档告诉我们我们可以为此使用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}]

You could sort the list of points based on a distance function then use the first one. 您可以根据距离函数对点列表进行排序,然后使用第一个。

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]

Learn about the sorted function here ==> https://wiki.python.org/moin/HowTo/Sorting . 在此处了解有关sorted函数的信息==> https://wiki.python.org/moin/HowTo/Sorting Iht think to look for is the key option in the sorted function. 我认为寻找是sorted功能中的key选项。

Once you know about the sorted function, you can just sort your dictionary, and to key, just supply the function to sort it with. 一旦知道排序后的函数,就可以对字典进行排序,并输入要对其进行排序的键。 Thus, let us say that you have the point p as 因此,让我们说您有点p

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

Then a function that takes this point and another and returns a dictance can be written as: 然后,将要指出这一点和另一个结果并返回命令的函数可以写成:

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

Now you can just sort the array, and take the first 3 points as: 现在,您可以对数组进行排序,并将前三点取为:

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