我一直在使用spatial.cKDTree中的scipy来计算点之间的距离。对于我的典型数据集,它总是运行得非常快(~1s)(查找~1000点到~1e6点数组的距离)。
我用Python2.7.6在Ubuntu14.10上运行这段代码。直到今天早上,我用apt-get管理了大多数python包,包括scipynumpy。不过,我想要几个包的最新版本,所以我决定在/usr/lib/python2.7/byapt-get中安装包,并在pip install中重新安装所有包(根据需要,处理scipy依赖项,如liblapack-devwithapt-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.cKDTreesklearn.neighbors.KDTree性能的经验。在某些人为的情况下(数据沿维度高度拉伸),它可能会产生负面影响,但通常应该更快。用cKDTree和/或balanced_tree=False建造compact_nodes=False的实验。将两者都设置为False将提供与0.15.x相同的行为。不幸的是,很难设置让每个人都高兴的默认值,因为性能取决于数据。
还要注意,使用balanced_tree=True我们在构建kd树时通过quickselect计算中介。如果出于某种原因对数据进行了预排序,则速度会非常慢。在这种情况下,它将有助于洗牌行的输入数据。或者可以设置balanced_tree=False以避免部分流沙。
还有一个新的选项是多线程最近邻查询。试着用queryn_jobs=-1打电话,看看它是否对你有帮助。

10-08 00:32