我一直在使用spatial.cKDTree
中的scipy
来计算点之间的距离。对于我的典型数据集,它总是运行得非常快(~1s)(查找~1000点到~1e6点数组的距离)。
我用Python2.7.6在Ubuntu14.10上运行这段代码。直到今天早上,我用apt-get
管理了大多数python包,包括scipy
和numpy
。不过,我想要几个包的最新版本,所以我决定在/usr/lib/python2.7/
byapt-get
中安装包,并在pip install
中重新安装所有包(根据需要,处理scipy
依赖项,如liblapack-dev
withapt-get
)。所有的东西都安装好了,而且可以毫无问题地导入。
import scipy
import cython
scipy.__version__
'0.16.0'
cython.__version__
'0.22.1'
现在,在相同大小的数据集上运行
spatial.cKDTree
非常缓慢。我看到的运行时间是~500秒,而不是~1秒。我很难搞清楚发生了什么。关于我在安装时使用
pip
而不是apt-get
可能会导致scipy.spatial.cKDTree
运行如此缓慢的建议? 最佳答案
在0.16.x
中,我添加了使用中值或滑动中点规则构建cKDTree
的选项,并选择是否重新计算kd树中每个节点的边界超矩形。默认值基于有关scipy.spatial.cKDTree
和sklearn.neighbors.KDTree
性能的经验。在某些人为的情况下(数据沿维度高度拉伸),它可能会产生负面影响,但通常应该更快。用cKDTree
和/或balanced_tree=False
建造compact_nodes=False
的实验。将两者都设置为False
将提供与0.15.x
相同的行为。不幸的是,很难设置让每个人都高兴的默认值,因为性能取决于数据。
还要注意,使用balanced_tree=True
我们在构建kd树时通过quickselect计算中介。如果出于某种原因对数据进行了预排序,则速度会非常慢。在这种情况下,它将有助于洗牌行的输入数据。或者可以设置balanced_tree=False
以避免部分流沙。
还有一个新的选项是多线程最近邻查询。试着用query
给n_jobs=-1
打电话,看看它是否对你有帮助。