我正在研究一个问题,即我在三维空间中有一个大集(> 400万)数据点,每个数据点都有一个标量函数值。这由四个阵列表示:XD,YD,ZD和FD。元组(XD [i],YD [i],ZD [i])指的是数据点i的位置,其值为FD [i]。
我想在与我的数据相同的空间中叠加一个直线网格,例如100x100x100点。该网格设置如下。
[XGrid, YGrid, ZGrid] = np.mgrid[Xmin:Xmax:Xstep, Ymin:Ymax:Ystep, Zmin:Zmax:Zstep]
XG = XGrid[:,0,0]
YG = YGrid[0,:,0]
ZG = ZGrid[0,0,:]
XGrid是网格中每个点的x值的3D数组。 XG是从Xmin到Xmax的x值的一维数组,以XStep的距离分隔。
我想使用插值算法,我必须根据周围的数据在每个网格点找到函数的值。在该算法中,我需要最接近(或至少接近)我感兴趣的网格点的20个数据点。也就是说,对于网格点(XG [i],YG [j],ZG [k]),我想找到20个最接近的数据点。
我能想到的唯一方法是让一个for循环遍历每个数据点,然后一个嵌入式for循环遍历所有(那么多!)数据点,计算欧几里德距离,并选出最接近的20个的。
for i in range(0,XG.shape):
for j in range(0,YG.shape):
for k in range(0,ZG.shape):
Distance = np.zeros([XD.shape])
for a in range(0,XD.shape):
Distance[a] = (XD[a] - XG[i])**2 + (YD[a] - YG[j])**2 + (ZD[a] - ZG[k])**2
B = np.zeros([20], int)
for a in range(0,20):
indx = np.argmin(Distance)
B[a] = indx
Distance[indx] = float(inf)
这将给出一个数组B,它是最接近网格点的数据点的索引。我觉得这需要很长时间才能遍历每个网格点的每个数据点。
我正在寻找任何建议,例如在计算距离之前我如何组织数据点,这可以减少计算时间。
答案 0 :(得分:1)
看一下看似相似的2D problem并看看你是否无法通过那里的想法改进。
从我的头脑中,我认为你可以根据它们的坐标(三个独立的阵列)对点进行排序。当您需要距离[X, Y, Z]
网格点最近的点时,您可以快速找到这三个数组中的点并从那里开始。
答案 1 :(得分:1)
另外,你真的不需要欧几里德距离,因为你只对相对距离感兴趣,也可以描述为:
abs(deltaX) + abs(deltaY) + abs(deltaZ)
除了昂贵的力量和平方根......
答案 2 :(得分:0)
无需为每个网格位置迭代数据点:您的网格位置本质上是有序的,因此只需迭代数据点一次,并将每个数据点分配到八个网格位置环绕它。完成后,某些网格位置可能只有太少的数据点。检查相邻网格位置的数据点。如果您有足够的数据点(取决于数据的分布方式),您可以在初始传递期间选择20个最近的邻居。
附录:您可能还想重新考虑算法的其他部分。您的算法是一种分段线性插值,并且有很多相对简单的改进。不要将空间划分为均匀间隔的立方体,而是考虑分配多个中心点并动态重新定位它们,直到最近中心点的数据点的平均距离最小化,如下所示: