重複なく
というのをどういったルールで取得するかによりますが
とりあえず見つかったものを除外しながらループ処理していけばできます。
当然、最近傍点が複数存在する場合、target, dataの各点の並び順などにより結果が異なりえます。
Python
1import numpy as np
2from scipy.spatial import KDTree
3
4target = np.array([[1,1],[2,2],[3,3]])
5data = np.array([[1.1,1.1],[1.4,1.4],[2.9,2.9]])
6
7ret = []
8for d in data:
9 kdtree = KDTree(target)
10 idx = kdtree.query(d)[1]
11 ret.append((d,target[idx]))
12 target = np.delete(target, idx, 0)
13
14print(ret) # [(array([1.1, 1.1]), array([1, 1])), (array([1.4, 1.4]), array([2, 2])), (array([2.9, 2.9]), array([3, 3]))]
なお、上記の方法だと、データによっては直観に反した(不自然な)採り方をすることがありえます。
以下のように、複数のdata
とtarget
の中から最も距離の小さい最近傍点のペアを取り除きつつループしたほうがより自然になるかと思います。
Python
1import numpy as np
2from scipy.spatial import KDTree
3
4target = np.array([[1,1],[2,2],[3,3]])
5data = np.array([[1.1,1.1],[1.4,1.4],[2.9,2.9]])
6
7ret = []
8while target.shape[0] > 0 and data.shape[0] > 0:
9 kdtree = KDTree(target)
10 dis, ids = kdtree.query(data)
11 dat_i = dis.argmin() # 最も距離の近いペアの位置
12 tar_i = ids[dat_i]
13 ret.append((data[dat_i], target[tar_i]))
14 data = np.delete(data, dat_i, 0)
15 target = np.delete(target, tar_i, 0)
16
17print(ret) # [(array([1.1, 1.1]), array([1, 1])), (array([2.9, 2.9]), array([3, 3])), (array([1.4, 1.4]), array([2, 2]))]