Python cKDTree vs dsearchn
我有两个数组Python cKDTree vs dsearchn,python,arrays,matlab,scipy,Python,Arrays,Matlab,Scipy,我有两个数组(A,B),包含:ID,x,y,z,它们的点数相同,但略有不同。 我想要一个数组,其中每一行都有两个数组中最近的两个点的ID x y z。 目前,我有以下几点: import numpy as np from scipy.spatial import cKDTree A = np.loadtxt('A.txt') B = np.loadtxt('B.txt') tree = cKDTree( B[:,[1,2,3]] ) d, inds = tree.query( A[:,[1,2,
(A,B)
,包含:ID
,x
,y
,z
,它们的点数相同,但略有不同。
我想要一个数组,其中每一行都有两个数组中最近的两个点的ID x y z
。
目前,我有以下几点:
import numpy as np
from scipy.spatial import cKDTree
A = np.loadtxt('A.txt')
B = np.loadtxt('B.txt')
tree = cKDTree( B[:,[1,2,3]] )
d, inds = tree.query( A[:,[1,2,3]], k=1, p=np.inf, eps=0.0)
A_new = A[inds]
xyz_near = np.hstack(( B[:,0:4], A_new[:,0:4] ))
但是附近的数组xyz_不包含正确的耦合(IDB xB yB zB DIA xA yA zA):
1258718.04450.0784-7.470534218.04440.0403-7.4639
12588 18.0447 0.0783-7.22313421 18.0446 0.0402-7.2164
12589 18.0450 0.0781-6.9756 7764 18.0461 0.0400-5.9785
1259018.04520.0779-6.7281776518.04640.0399-5.7310
1259118.04540.0777-6.4805776618.04670.0399-5.4835
1259218.04570.0775-6.2329776718.04700.0398-5.2359
1259318.04590.0773-5.9852776818.04730.0398-4.9884
如您所见,前两行是正确的,但下一行不是
如果我在matlab中使用dsearchn
(IDB xB yB zB DIA xA yA zA)执行相同的操作:
1258718.04450.0784-7.470534218.04440.0403-7.4639
12588 18.0447 0.0783-7.22313421 18.0446 0.0402-7.2164
12589 18.0450 0.0781-6.9756 3420 18.0448 0.0402-6.9688
12590 18.0452 0.0779-6.7281 3419 18.0450 0.0401-6.7212
1259118.04540.0777-6.4805341818.04530.0401-6.4737
12592 18.0457 0.0775-6.2329 3417 18.0455 0.0400-6.2261
1259318.04590.0773-5.9852341618.04580.0400-5.9785
没错。
我曾尝试将p
更改为1、2和np.inf
,但结果相同
档案:
A.txt:
B.txt:
谢谢
更新:
即使使用ergo_uu建议的修复方法,我还是得到了:
12587 18.0445 0.0784-7.4705 7758 18.0448 0.0403-7.4639
1258718.04450.0784-7.470534218.04440.0403-7.4639
12588 18.0447 0.0783-7.22313421 18.0446 0.0402-7.2164
12588 18.0447 0.0783-7.2231 7759 18.0450 0.0402-7.2163
12589 18.0450 0.0781-6.9756 7760 18.0452 0.0402-6.9688
12589 18.0450 0.0781-6.9756 3420 18.0448 0.0402-6.9688
12590 18.0452 0.0779-6.7281 3419 18.0450 0.0401-6.7212
1259018.04520.0779-6.7281776118.04540.0401-6.7212
1259118.04540.0777-6.4805776218.04560.0401-6.4736
1259118.04540.0777-6.4805341818.04530.0401-6.4737
因此,它会多次考虑相同的点。您可以验证cKDTree是否给出了正确的结果。
这里,对于“A中的每个点,B中的哪个点最接近”的问题:
解决方案也是独一无二的,如上所示
另一方面,如果您想要1对1映射,这是一个不同的问题,这在中给出
但是,我不认为dsearchn
给出了这个答案。使用八度音阶的dsearchn
或不带三角剖分的Matlab可以引入以下numpy/python代码行:
def dsearchn(x,y):
"""
Implement Octave / Matlab dsearchn without triangulation
:param x: Search Points in
:param y: Were points are stored
:return: indices of points of x which have minimal distance to points of y
"""
IDX = []
for line in range(y.shape[0]):
distances = np.sqrt(np.sum(np.power(x - y[line, :], 2), axis=1))
found_min_dist_ind = (np.min(distances, axis=0) == distances)
length = found_min_dist_ind.shape[0]
IDX.append(np.array(range(length))[found_min_dist_ind][0])
return np.array(IDX)
试试这个代码。它产生的结果与使用三角剖分的MATLAB方法“dsearchn(P,T,PQ)”相同
# xy=[[x1,y1]...[xm,ym]]
# XY=[[X1,Y1]...[Xm,Ym]]
tree = cKDTree(xy[:, 1:])
dd, ii = tree.query(XY, k=2, p=2, eps=0.0)
Z = []
for i in range(len(dd)):
min_dd = min(dd[i])
min_dd_idx = np.where(dd[i] == min_dd)[0]
if len(min_dd_idx) > 1:
sorted_ii = np.sort(ii[i][min_dd_idx])
Z.append(sorted_ii[len(min_dd_idx) - 1])
else:
Z.append(ii[i][0])
从#scipy频道复制粘贴:而不是A_new=A[inds],多亏了你和ergo,你应该做B_new=B[inds]
。似乎有效。不幸的是,即使使用B_new=B[inds],我也无法看到更新。你得到的答案是“对于A中的每个点,B中的哪个点最接近”,这自然不需要列出B中的所有点。如果你想问相反的问题,请交换A和B。但我不明白为什么使用“dsearchn”我不会遇到这个问题。即使我不交换A和B,我也会得到A的多个引用。
# xy=[[x1,y1]...[xm,ym]]
# XY=[[X1,Y1]...[Xm,Ym]]
tree = cKDTree(xy[:, 1:])
dd, ii = tree.query(XY, k=2, p=2, eps=0.0)
Z = []
for i in range(len(dd)):
min_dd = min(dd[i])
min_dd_idx = np.where(dd[i] == min_dd)[0]
if len(min_dd_idx) > 1:
sorted_ii = np.sort(ii[i][min_dd_idx])
Z.append(sorted_ii[len(min_dd_idx) - 1])
else:
Z.append(ii[i][0])