我一直在spatial.cKDTree
中使用scipy
来计算点之间的距离。对于我的典型数据集,它总是运行得非常快(~1秒)(找到~1000点的距离到~1e6点的数组)。
我在使用Ubuntu 14.10的计算机上运行python 2.7.6中的代码。直到今天早上,我使用apt-get
管理了大多数python包,包括scipy
和numpy
。我想要一些软件包的最新版本,所以我决定在/usr/lib/python2.7/
apt-get
安装软件包,然后用pip install
重新安装所有软件包(照顾{ {1}} scipy
与liblapack-dev
之类的依赖关系(如果需要)。安装好的所有东西都是可以导入的,没有任何问题。
apt-get
现在,在相同大小的数据集上运行import scipy
import cython
scipy.__version__
'0.16.0'
cython.__version__
'0.22.1'
的速度非常慢。我看到的运行时间约为500秒而不是~1秒。我无法弄清楚发生了什么。
有关使用spatial.cKDTree
而不是pip
进行安装可能会导致apt-get
运行速度过慢的建议吗?
答案 0 :(得分:10)
在0.16.x
中,我添加了使用中位数或滑动中点规则构建cKDTree
的选项,以及选择是否重新计算kd-tree中每个节点的边界超直角。默认值基于scipy.spatial.cKDTree
和sklearn.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的,那么它已经可用。