scipy - 了解 scipy.spatial.KDTree 中的 `leafsize`
问题描述
问题陈述:
我在 3D 空间中有 150k 个点,它们的坐标存储在尺寸为 [150k, 3] 的矩阵中,以 mm 为单位。
我想找到p
半径内给定点的所有邻居r
。我想以最准确的方式做到这一点。
我应该如何选择我的leafsize
参数?
from scipy.spatial import KDTree
import numpy as np
pts = np.random.rand(150000,3)
T1 = KDTree(pts, leafsize=20)
T2 = KDTree(pts, leafsize=1)
neighbors1= T1.query_ball_point((0.3,0.2,0.1), r=2.0)
neighbors2= T2.query_ball_point((0.3,0.2,0.1), r=2.0)
np.allclose(sorted(neighbors1), sorted(neighbors2))
True
解决方案
该函数query_ball_point
将为任何版本的搜索树返回正确的点集。该leafsize
参数不影响查询的结果,只影响结果的性能。
想象一下下面显示的两棵树用于相同的数据(但不同的叶子大小参数)和一个搜索红色圆圈内所有点的查询。
在这两种情况下,代码都只会返回红圈内的两个点。这是通过检查与圆相交的树的所有框中的所有点来完成的。这导致每种情况下的工作量不同(即不同的性能)。对于左树(对应更大的叶子大小),算法必须检查圆内是否有 13 个点(上相交框中有 6 个,下相交框中有 7 个)。在右树(叶子尺寸较小)中,只处理了三个点(一个在上相交框中,两个在下相交框中)。
按照这个逻辑,您可能认为总是使用较小的叶子大小才有意义:这将最大限度地减少算法结束时的实际比较次数(确定点是否实际位于查询区域中)。但这并不是那么简单:较小的叶子大小将生成更深的树,从而增加了构建时间和树遍历时间的成本。在树遍历性能与叶级比较之间取得适当的平衡实际上取决于进入树的数据类型以及您正在进行的特定叶级比较。这就是为什么 scipy 提供 Leafsize 参数作为参数,以便您可以调整事物以在特定算法上表现最佳。
推荐阅读
- tizen - genlist的水平滚动
- java - 如何交换字符串数组中的值?
- android - 如何在 Kotlin 中获取执行输出?
- regex - 正则表达式忽略以特定模式结尾的字符串
- javascript - 在 Service Worker 中使用 performance.now() 获取 API 响应时间
- python - MySQL BIGINT 插入不一致?
- python - Model A 和 Model B 的关系是基于 django 中 Model A 信息过滤器中关于 Model B 的信息显示
- visual-studio - 为什么 Cyclonedds 不能为 vs2013 构建?
- spring - 如何创建自定义 SAML 身份验证流程
- python - 无法打开图像文件 Azure Blob 存储