2012-03-20 15 views
1

私は数日間このものを使って遊んでいて、パフォーマンスの壁にぶち当たっています。3D空間内の特定の軸に沿った最も近い点を効率的に見つける

データ:3Dの数十万人に

  • 10sが
  • ポイントは、正/負のint型であり、
  • めったに新しいポイント
  • を追加しません重複なしで3Dグリッドの上に落ちるポイント通常はギャップレスですが、ギャップは可能です

構造:

  • 各軸(最も近い点を左に)に最も近い隣接点を効率的に見つけることができ、軸のみである必要があります。
  • がまれに挿入を処理していないか(しかし、それらを処理する必要があります)
  • は私がhttp://docs.scipy.org/doc/scipy/reference/spatial.htmlで可能な解決策を発見した重複ポイント

を処理する必要はありません建設後に削除されます、しかし、kd木は非常に無駄のようですこのタイプのデータ(任意の点のクラスタに適しています)に対して、半径内の点を見つけるために調整されます。このデータの主な使用事例は、それぞれに沿って最も近い近傍点を見つけ出す(そして追跡する)ことが多い。

例データ(X、Y、Z):

[(4, 3, 0), (4, 4, 0), (5, 3, 0), (3, 3, 0), (4, 3, 1), ...] 

は、おそらく私のグーグル-FUは、(好ましくは、Pythonで)既に私と最適な構造が存在する失敗しているが、私は1つを見つけることができませんでした。

+0

私はあなたの答えがありませんが、私はあなたがそのような様々な分析を必要としているしようとしているものについて興味があります。 –

+0

飛行機でこれをやっていますか?選択したポイントと他のポイントとの絶対的な差異によってリストをソートするのはどうですか? – Ben

+0

@burhanこれは、[minecraft](http://minecraft.net)地形エディタライブラリです。既存のライブラリ(例:[pymclevel](https://github.com/mcedit/pymclevel))は非常に乱雑で非効率的です。このアプローチは、既存の世界フォーマットのどれかを単純な抽象化によってサポートすることを目的としています。その抽象化によって、固定サイズのチャンクにグリッドを分割し、そのグリッドの効率的なトラバーサルを実現します。それがなければ、少しの点があります。 – TkTech

答えて

3

、xに対するyの3 KDツリーを構築については、zはそれぞれ軸は? とにかくIMOのような木構造が必要です。

+0

勝利のためのkd-tree!問題のための完全なデータ構造のように聞こえる。 – wheaties

0

Hmm、x = 4。で複数の点を言っているので、「左に最も近い」とそれ以外のものは厄介であると判明するので、他の軸での閉じを見つける必要があります。

次のようなもっと単純な「最近点」は機能しませんか?

for n in xrange(len(points)): 
    diff = (((x0-points.x[n])**2) + ((y0-points.y[n])**2) + ((z0-points.z[n])**2))**0.5 

そしてちょうど最小の差分(含まれている場合、現在の点を除く)と 'N' を取り除く..:/

+0

最後に** 0.5は必要ありませんが、私が理解するところでは、実際の距離ではなく、最も近い点を特定することです(最も近い点に適用するだけで時間を節約できます)。 – deinonychusaur

0

点だけが、他の軸の値が静的である軸をたどっている場合、点が最も近いものとして数えられている場合。それは、(1,1,0)の資格ではないでしょう(0,0,0)が、(4,0,0)のように最も近いだろう、あなた可能性:

import numpy as np 
#The .T is ofcourse not neccesary here but then you have to fix it below as well. 
points = np.asarray([(4, 3, 0), (4, 4, 0), (5, 3, 0), (3, 3, 0), (4, 3, 1)]).T 
#You have still to check thiss for all points just showing for pt 0 
on_same_xy = (points[:-1,:].T == points[:-1,0]).all(axis=1) 

z_distance = (points[2,on_same_xy] - points[2,0]) 
z_distance_up = z_distance[np.where(z_distance > 0)] 
if z_distance_up.size == 0: 
    up = None 
else: 
    up = z_distance_up.min() 

z_distance_down = z_distance[np.where(z_distance < 0)] 
if z_distance_down.size == 0: 
    down = None 
else: 
    down = z_distance_down.max() 

print "Z-up-neighbour %s, Z-down-neighbour %s" % (str(up), str(down)) 

あなたはちょうど2つの第1の座標値を持っているので、ポイント[-1,0]のうち、アップポイントおよびダウンポイントの位置ならびに距離は、上下からアクセスすることができる。

コードがちょっと混乱していることがわかりました。しかし、大量のデータセットがいったん無駄になったら、本当に速く動作するはずです。また、再度、あなたの質問が何を求めているのかという質問です。

関連する問題