【问题标题】:Finding closest values in a list of dictionary keys Python在字典键Python列表中查找最接近的值
【发布时间】:2014-02-18 00:15:27
【问题描述】:

给出一个观点:

      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.

有什么想法或建议吗?

【问题讨论】:

  • 您可以使用具有预测功能的支持向量机内核scikit-learn.org/stable/modules/svm.html。每个“坐标”都可以定义为一个多分类任务; a = [[X],[Y],[Z]]/[X,Y,Z] 和 clf.predict。
  • 你觉得问题的哪一部分最困难? python实现或“给定输入点x找到列表中最接近的点”的算法问题?这是为了了解您是否需要有关如何操作 python 的列表和字典的建议。
  • 像这样的物理问题我可以解决,但这并不意味着我可以用 Python 编写它,我还是个菜鸟!我只需要一些有关 Python 实现和操作复杂列表/字典的指导。
  • 如果您的点列表不短,请注意时间复杂度。您的问题类似于this,但在 3D 上工作您需要在 3D 中同时使用 sorts points 的东西

标签: python list dictionary


【解决方案1】:

您可以保留一个反向查找表,在其中返回键值对并将坐标存储为键。这很容易实现。然后您可以再次返回键并在每个坐标上执行距离公式。

如你所知,距离公式是:

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

注意:您的列表中似乎有 3 个不同的词典。

【讨论】:

  • 我看到了简单!谢谢 JFA。
【解决方案2】:

最接近 意味着您定义了一个距离函数。对于空间中的一个点,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

让 python 执行boring work

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

为了理解这个函数,python 将遍历列表的元素(每个字典),对它们应用 key 函数(这将计算范数 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}]

【讨论】:

    【解决方案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]
    

    【讨论】:

      【解决方案4】:

      在此处了解 sorted 函数 ==> https://wiki.python.org/moin/HowTo/Sorting。我想寻找的是sorted 函数中的key 选项。

      一旦您了解了 sorted 函数,您就可以对字典进行排序,并且要键入,只需提供对其进行排序的函数即可。因此,让我们说您的观点p as

      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]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-23
        • 1970-01-01
        • 2014-03-14
        • 2015-04-24
        • 2013-11-06
        • 1970-01-01
        • 2021-11-20
        相关资源
        最近更新 更多