Scipy.spatial.ckdtree исчерпывает память для большого набора данных - PullRequest
2 голосов
/ 11 октября 2019

У меня есть два больших набора координат A и B, оба определены в одной и той же области.

Для каждой точки в A я хочу узнать количество соседей типа A, максимальное расстояние до которыхточка - это r, а также число соседей типа B. Поскольку мои данные большие, A содержит 262 001 пункт, а B содержит ~ 340 000 точек, я использую функцию cKDTree из Scipy.spatial.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, который лучше подходит для моего случая?

...