scipy.spatial.ckdtree慢慢跑

时间:2015-08-04 21:35:36

标签: python performance scipy

我一直在spatial.cKDTree中使用scipy来计算点之间的距离。对于我的典型数据集,它总是运行得非常快(~1秒)(找到~1000点的距离到~1e6点的数组)。

我在使用Ubuntu 14.10的计算机上运行python 2.7.6中的代码。直到今天早上,我使用apt-get管理了大多数python包,包括scipynumpy。我想要一些软件包的最新版本,所以我决定在/usr/lib/python2.7/ apt-get安装软件包,然后用pip install重新安装所有软件包(照顾{ {1}} scipyliblapack-dev之类的依赖关系(如果需要)。安装好的所有东西都是可以导入的,没有任何问题。

apt-get

现在,在相同大小的数据集上运行import scipy import cython scipy.__version__ '0.16.0' cython.__version__ '0.22.1' 的速度非常慢。我看到的运行时间约为500秒而不是~1秒。我无法弄清楚发生了什么。

有关使用spatial.cKDTree而不是pip进行安装可能会导致apt-get运行速度过慢的建议吗?

2 个答案:

答案 0 :(得分:10)

0.16.x中,我添加了使用中位数或滑动中点规则构建cKDTree的选项,以及选择是否重新计算kd-tree中每个节点的边界超直角。默认值基于scipy.spatial.cKDTreesklearn.neighbors.KDTree的效果经验。在一些人为的情况下(沿着维度高度拉伸的数据),它可能会产生负面影响,但通常它应该更快。尝试使用cKDTree和/或balanced_tree=False来构建compact_nodes=False。将两者都设置为False可以获得与0.15.x相同的行为。不幸的是,很难设置让每个人都满意的默认值,因为性能取决于数据。

另请注意,对于balanced_tree=True,我们通过在构造kd树时快速选择来计算中位数。如果由于某种原因数据是预先排序的,那么它将非常慢。在这种情况下,它将有助于改变输入数据的行。或者,您可以设置balanced_tree=False以避免部分快速排序。

还有一个用于多线程最近邻居查询的新选项。尝试使用query致电n_jobs=-1并查看它是否对您有所帮助。

答案 1 :(得分:0)

在下一版SciPy中,将使用introselect而不是quickselect创建平衡的kd树,这在结构化数据集上要快得多。如果在结构化数据集(如图像或网格)上使用cKDTree,则可以期待性能的大幅提高。如果您是从GitHub的master分支构建SciPy的,那么它已经可用。