簡體   English   中英

匹配Python字典中的實數鍵

[英]Matching a real number key in a Python dictionary

我有一個字典,提供從實數元組到標識整數的映射。 給定一個包含數字的元組列表,這些數字在容差范圍內,但不完全等於字典中的容差,我想生成一個相應整數的列表。

例:

tdict = {(0.334, 0.333, 0.333):1, (0.167, 0.666, 0.167):2, (0.5, 0.5, 0):3}
tlist = [(0.333, 0.333, 0.333), (0.16667, 0.6666667, 0.17), (0.34, 0.33, 0.33), (0.5001, 0.4999, 0.0)]
tol = 0.01

運行我想要的代碼應該產生結果

ilist = [1,2,1,3]

因為每個元組中的所有數字都在tdict相應元組中的tdict的給定容差范圍內。 我可以通過迭代tdict.keys()並單獨比較每個,但我覺得應該有更好的方法。 獲取相應整數到這些元組的最有效方法是什么? 它不需要涉及字典,這對我來說似乎是最自然的。 我正在使用Python 3。

您顯然希望在具有特定網格間距(與您的公差值直接相關)的3D網格上的3D空間中投影點,並創建某種直方圖。 給自己寫一個投影函數:它將一個任意的3元素列表/元組(一個描述空間中的點的向量)作為參數,並將其投影到某個網格點上。 你這樣做是為了填寫你的字典以及閱讀它。 此外,關於字典中的鍵,我認為你應該使用整數元組而不是浮點數,因為我不確定浮點數是否可以相同。

這是一個實現示例:

from collections import defaultdict
from random import random as rn

class Grid(object):
    def __init__(self, spacing):
        self.spacing = spacing
        self.griddict = defaultdict(int)

    def add_point(self, coords):
        """
        `vid`, a voxel id, is a tuple of indices, indicating one grid
        bin for each dimension, e.g. (1, 5, 2)
        rule: i_x = int(floor(x_coord / spacing))
        """
        vid = tuple([int(c//self.spacing) for c in coords])
        self.griddict[vid] += 1

    def get_point(self, coords):
        vid = tuple([int(c//self.spacing) for c in coords])
        return self.griddict[vid]

    def vid_centercoords(self, vid):
        """
        Return the real coordinates in space for a certain voxel,
        which is identified by its voxel id `vid` (a tuple of indices).
        """
        return tuple([(i-1)*self.spacing + self.spacing/2 for i in vid])



N = 20
fillpoints = [(rn(),rn(),rn()) for _ in xrange(N)]
testpoints = [(rn(),rn(),rn()) for _ in xrange(N)]

grid = Grid(spacing=0.3)

for p in fillpoints:
    grid.add_point(p)

print [grid.get_point(p) for p in testpoints]

它的作用:它在3D空間中創建20個隨機向量(所有坐標在0和1之間)。 它使用空間中的這些點填充3D網格。 網格在每個維度上的間距為0.3。 空間中的這20個點中的每一個被分配給網格中的某個體素(僅用於3D像素的單詞)。 每個賦值將相應體素的計數器增加1(將網格渲染為直方圖)。 然后,使用另一組隨機的20個向量來讀出體素。 這些點再次投射到體素上,但這次計數器只是返回而不是增加。 執行測試:

$ python gridtest.py 
[2, 1, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]

執行您的數據:

fillpoints = [(0.334, 0.333, 0.333), (0.167, 0.666, 0.167), (0.167, 0.666, 0.167), (0.5, 0.5, 0), (0.5, 0.5, 0), (0.5, 0.5, 0)]
testpoints = [(0.333, 0.333, 0.333), (0.16667, 0.6666667, 0.17), (0.34, 0.33, 0.33), (0.5001, 0.4999, 0.0)]

grid = Grid(spacing=0.03)
for p in fillpoints:
    grid.add_point(p)
print [grid.get_point(p) for p in testpoints]

它根據需要打印[1, 2, 1, 3] 1,2,1,3 [1, 2, 1, 3] 我沒有深入考慮關系spacing=3*tolerance 這可能是錯的。 我只知道存在確定性關系。 證明/找到這個公式是留給你作為一個練習:)

  1. 按順序將tdict.keys()按距離排序到每個tlist點。
  2. 選擇前幾個並在tdict查找它們。

如果你有權訪問numpy,你可以使用numpy.allclose來檢查匹配:

>>> import numpy
>>> numpy.allclose((0.334, 0.333, 0.333), (0.333, 0.333, 0.333))
False
>>> numpy.allclose((0.334, 0.333, 0.333), (0.333, 0.333, 0.333), atol=0.1)
True

您可以查找功能(查找元組的圓形版本):

def look_up_tdict( t ):
    return tdict[ (float('%.3f' % t[0]),
                   float('%.3f' % t[1]),
                   float('%.3f' % t[2])
                 ]

注意:如果字典中沒有任何內容接近t則會出錯。 然后你可以填充ilist

ilist = [ look_up_tdict(t) for t in tlist ]
 tolerance = 0.1
 for i in tlist:
      list2 = filter(lambda x:abs(sum(i)-sum(x))<tolerance,tdict
      print [tdict[itm] for itm in list2]

我認為這樣可行......雖然不是正面的......事實上它看起來並沒有給你所需的輸出

暫無
暫無

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

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