web-dev-qa-db-ja.com

特定の距離内のすべての最近傍を検索します

numpy配列に保存されたx座標とy座標の大きなリストがあります。

Coordinates = [[ 60037633 289492298]
 [ 60782468 289401668]
 [ 60057234 289419794]]
...
...

私が欲しいのは、特定の距離(3メートルとしましょう)内のすべての最近傍を見つけて結果を保存し、後でその結果をさらに分析できるようにすることです。

ほとんどのパッケージでは、NNの数を決定する必要がありますが、すべてを設定した距離内に収めたいだけです。

どうすればそのようなことを達成できますか?また、大規模なデータセット(数百万ポイント)でそのようなことを達成するための最速かつ最良の方法は何ですか?

15
Kitumijasi

scipy.spatial.cKDTree を使用できます:

import numpy as np
import scipy.spatial as spatial
points = np.array([(1, 2), (3, 4), (4, 5)])
point_tree = spatial.cKDTree(points)
# This finds the index of all points within distance 1 of [1.5,2.5].
print(point_tree.query_ball_point([1.5, 2.5], 1))
# [0]

# This gives the point in the KDTree which is within 1 unit of [1.5, 2.5]
print(point_tree.data[point_tree.query_ball_point([1.5, 2.5], 1)])
# [[1 2]]

# More than one point is within 3 units of [1.5, 1.6].
print(point_tree.data[point_tree.query_ball_point([1.5, 1.6], 3)])
# [[1 2]
#  [3 4]]

次の例は、point_tree.query_ball_pointを1回呼び出すだけで、ポイントの配列に最も近いすべての近傍を見つける方法を示しています。

import numpy as np
import scipy.spatial as spatial
import matplotlib.pyplot as plt
np.random.seed(2015)

centers = [(1, 2), (3, 4), (4, 5)]
points = np.concatenate([pt+np.random.random((10, 2))*0.5 
                         for pt in centers])
point_tree = spatial.cKDTree(points)

cmap = plt.get_cmap('copper')
colors = cmap(np.linspace(0, 1, len(centers)))
for center, group, color  in Zip(centers, point_tree.query_ball_point(centers, 0.5), colors):
   cluster = point_tree.data[group]
   x, y = cluster[:, 0], cluster[:, 1]
   plt.scatter(x, y, c=color, s=200)

plt.show()

enter image description here

17
unutbu