使用cKDTree()时的Python中的MemoryError.Query_ball_tree

时间:2013-08-06 11:27:10

标签: python scipy kdtree

我有大型2D阵列,带有未分类(X,Y)点,我需要知道哪些点彼此非常接近(最近邻查找)。我已经使用cKDTree和query_ball_tree成功获得了大约500,000(X,Y)点的数组。但是,当我为超过1,000,000个点的数据集尝试相同的算法时,query_ball_tree会导致MemoryError。

我使用带有16Gb内存的64位Windows,并尝试过32位和64位版本的Python以及扩展模块(scipy和numpy)。

def Construct_SearchTree(AllXyPoints):
    KDsearch = cKDTree(AllXyPoints)  
    return KDsearch.query_ball_tree(KDsearch, Maxdist)

我的问题:

1)有没有人知道cKDTree / query_ball_tree的替代品消耗更少的内存?在这种情况下,内存使用速度不太重要。

2)我希望从32位切换到64位python&扩展将解决MemoryError。这可能是什么原因呢?

感谢您的帮助和建议。

1 个答案:

答案 0 :(得分:4)

我在构建过程中遇到了MemoryError的SciPy cKDTree,在调用KDTree时遇到了scikit-learn .query_radius()。我发现Scikit-learn's BallTree内存效率更高,使用BallTree解决了我的问题。我在64位系统上测试了BallTree 100万个数据点。它仍然消耗我所有可用的内存(12GB)和一些交换空间,但我没有得到MemoryError

BallTree上的查询速度不会像KDTree那么快,因为您的数据是2D,而BallTree的速度比KDTree时的速度低cKDtree 3(见解释here)。但是,鉴于KDTree和scikit-learn的MemorError都提升BallTree s(在我的系统上,无论如何),最简单的解决方案是使用from sklearn.neighbors import BallTree import numpy as np max_dist = .1 points = np.random.normal(size=2000000).reshape(1000000, 2) #1 million points ball_tree = BallTree(points) neighbors = ball_tree.query_radius(points, max_dist)

Maxdist

根据您的BallTree.query_radius(),返回的结果会消耗大量内存(最多为O(n ^ 2)),但scikit-learn的np.array会返回np.array { {1}}而不是list list,因此它应该为您节省一些记忆(请参阅this answer以获得解释)。