假设我们有两个3D坐标点数组。
A =(1000000,3),浮点型,B =(100000,3),浮点型
对于A中的每个坐标,我想找到到B中任何坐标的最小欧氏距离。这意味着它应该计算A[0]与所有B之间的欧氏距离,然后取最小值。
我写了代码来使用循环来完成这一点。它工作,但由于我的数组的大小,它需要一个多小时才能完成。伪代码看起来像这样:
minDistances = np.zeros(A.shape)
for i in range(len(A)):
queriedPoint = A[i]
distances = B - queriedPoint
euclideanDistances = np.linalg.norm(distances, axis=1)
minDistance = np.min(euclideanDistances)
minDistances[i] = minDistance
字符串
理想情况下,我希望将其向量化,但这样做似乎会使我的程序因RAM使用而崩溃。对于如何更有效地做到这一点,有什么想法或提示吗?我在想,也许我可以把这个问题简化成更简单的问题,或者重新思考如何一起解决它。谢谢你,谢谢
4条答案
按热度按时间pjngdqdw1#
最快的方法可能是使用
scipy.spatial.KDTree
。proposed duplicate建议使用scipy.spatial.distance.cdist
,但您的数组太大,会占用太多内存。字符串
我不知道
A
和B
的实际取值范围,所以我只使用了(-100, 100)
。这需要大约2.2秒的时间来运行。iyzzxitl2#
蛮力将需要NxN距离计算。
更简单的方法是使用“桶”,即使用一些特殊的盒子。
构建盒子需要大约4N次计算。例如,第一遍确定每个数组的最大和最小X,Y,Z坐标。然后你把“空间”分成比如4x4x4=64个盒子,用于array_1,另外64个盒子用于array_2。
通过简单的顶点比较,您可以得到两个更接近的框(每个数组一个)。是的,这是蛮力,但数据量很小。
注意:如果盒子相交或有多个接近的对,那么你需要一个候选列表,更多的盒子,但仍然不是初始的大数据。
然后在数组上运行new pass。仅获取位于方框列表中的那些点。
最后,你可以运行一个蛮力与选定的点。
对于最小的情况,array_1的大多数框与array_2的一些框相交(或距离相同),然后只需将每个框分割成八个较小的框并再次检查。最坏的情况可能是(但很少)最坏的情况,即使用阵列的蛮力。
yrefmtwq3#
如果两个数组都是完全随机的数字,那么可能就没什么可做的了。如果每个数组对应于例如车辆轨迹,那么您应该查看Hausdorff距离和Fréchet度量。
r7knjye24#
是的,所以最好的办法就是把问题分成子问题,分而治之的算法;)所以给出了上面的伪代码,我们可以尝试利用dict & list理解来尝试它
字符串
通过使用dict和list理解,它们有助于优化时间和复杂性。希望能帮上忙
或者,您可以尝试基于循环的方法
型