首页 > 解决方案 > 大型数据集的 Scipy.spatial.ckdtree 耗尽内存

问题描述

我有两个大坐标集 A 和 B,都定义在同一个区域中。

对于A中的每个点,我想找出到该点的最大距离为r的A类型邻居的数量,以及B类型的邻居数量。由于我的数据很大,A包含262,001个点,并且B 包含约 340,000 个点,我使用 Scipy.spatial.cKDTree 中的 cKDTree 函数来完成我的工作。

我首先构建树:

import numpy as np
from Scipy.spatial import cKDTree
from Scipy.io import loadmat
from Scipy.stats import spearman's
import math
# load points
CD3_Points = np.array(load mat('./Points_Bivariate/Case 0/CD3_Points.mat)['x])/125
CD4_Points = np.array(load mat('./Points_Bivariate/Case 0/CD4_Points.mat)['x])/125
# construct tree
CD3_Tree = cKDTree(CD3_Points)
CD4_Tree = cKDTree(CD4_Points)

因为我对多半径距离的结果感兴趣,所以我写了一个 for 循环

A_list = np.array([]).reshape(len(CD3_Points), 0)
B_list = np.array([]).reshape(len(CD3_Points), 0)

for r in np.arrange(0.1, 2.8, 0.1):
    A_index = CD3_Tree.query_ball_tree((CD4_Tree, r = r))
    B_index = CD4_Tree.query_ball_tree((CD4_Tree, r = r))
    # get the number
    A_num = np.asarray(list(map(len, A_sub))).reshape(len(CD3_Points),1)
    B_num = np.asarray(list(map(len, B_sub))).reshape(len(CD3_Points),1)
    # append to store data
    A_list = np.append(A_list, A_num, axis = 1) 
    B_list = np.append(B_list, B_num, axis = 1) 

在那种情况下,我假设我可以获得两个数组。对于每个数组,每一列代表一个半径上所有点的搜索结果。

最初运行良好,但是当 r 变为 0.4 时出现错误:

进程以退出代码 137 结束(被信号 9 中断:SIGKILL)

我认为这是因为我的数据集是两个大的,所以我没有将“CD4_Points”的所有点放入函数中,而是使用 for 循环将 CD4_Points 的单个元素放入函数中,现在看起来像:

for its in range(0, len(CD3_Points)):
    Point = CD3_Points[pts,]
    for r in np.arange(0.1, 2.8, 0.1):
        A_num = len(CD3_Tree.query_ball_point(Point, r = r))
        B_num = len(CD4_Tree.query_ball_point(Point, r = r))
        A.append(A, A_num)
        B.append(A, A_num)

    rho, oval = spearmanr(A, B)
    A = []
    B = []

        ...

这似乎有效,但它真的很耗时......有什么解决方案可以让它更快吗?另外,我还注意到还有其他类型的搜索方法,比如球树,sklearn 也有 cKDTree 和 KDTree,哪一种更适合我的情况?

标签: pythonscikit-learnscipynearest-neighborkdtree

解决方案


推荐阅读