3

実数タプルから識別整数へのマッピングを提供する辞書があります。許容範囲内であるが、辞書内の数値と正確に等しくない数値を含むタプルのリストを前提として、対応する整数のリストを作成したいと思います。

例:

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.keys()それぞれを個別に比較することで実現できますが、もっと良い方法があるはずだと思います。これらのタプルに対応する整数を取得するための最も効率的な方法は何ですか?辞書を使う必要はありません。それは私にとって最も自然なことのように思えました。私はPython3を使用しています。

4

5 に答える 5

6

明らかに、特定のグリッド間隔(許容値に直接関連する)を使用して3Dグリッド上の3D空間にポイントを投影し、ある種のヒストグラムを作成する必要があります。自分で射影関数を作成します。任意の3要素のリスト/タプル(空間内の点を表すベクトル)を引数として取り、それを特定のグリッド点に射影します。これは、辞書に記入するためと、辞書を読み取るために行います。さらに、辞書のキーに関しては、floatが同一になるかどうかわからないため、floatではなく整数のタプルを使用する必要があると思います。

これは実装例です。

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]します。私はその関係について深く考えていませんspacing=3*tolerance。おそらく間違っています。私は決定論的な関係があることを知っているだけです。この式を証明/見つけることは演習としてあなたに任されています:)

于 2012-08-31T16:03:31.243 に答える
2
  1. tdict.keys()順番に各ポイントまでの距離で並べ替えtlistます。
  2. 最初のいくつかを選び、で調べてくださいtdict
于 2012-08-31T16:03:10.303 に答える
2

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
于 2012-08-31T16:15:46.263 に答える
1

ルックアップ関数(タプルの丸められたバージョンを検索する)を作成できます。

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 ]
于 2012-08-31T16:11:25.783 に答える
0
 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]

私はそれがうまくいくと思います...しかしポジティブではありません...実際にはそれはあなたにあなたの望む出力を完全に与えていないように見えます

于 2012-08-31T16:06:37.247 に答える