Почему KDTree от Scipy такой медленный?

Допустим, у меня есть около 100 наборов по 100 точек, и я хочу узнать, какие точки находятся на заданном расстоянии друг от друга. У меня есть две реализации этого, одна с использованием дерева k-d, а другая просто получает попарные расстояния:

from scipy.spatial.distance import cdist
from scipy.spatial import KDTree
from itertools import combinations
import numpy
import time

pts = [numpy.random.randn(100,2) for x in range(100)]


start = time.time()

for p1, p2 in combinations(pts,2):
    numpy.argwhere(cdist(p1, p2) < 0.5)

print(time.time() - start)


start = time.time()

trees = [KDTree(x) for x in pts]

for p1, p2 in combinations(trees,2):
    p1.query_ball_tree(p2,0.5,eps=1)

print(time.time() - start)

На моей машине cdist занимает 0,5 секунды, тогда как реализация KDTree занимает целую минуту. Строительство деревьев занимает 0,03 секунды. Я ожидаю, что метод KDTree будет быстрее, поскольку ему не нужно рассматривать все возможные пары точек.

Итак, что я не так понял, и можно ли это сделать быстрее?


person TDN169    schedule 04.05.2016    source источник
comment
Возможно ли, что построение деревьев связано с накладными расходами, которые не амортизируются, учитывая относительно небольшой размер ваших данных? Вставьте print(time.time() - start) после trees = ..., чтобы узнать   -  person gboffi    schedule 04.05.2016
comment
Построение дерева занимает 0,032 секунды   -  person TDN169    schedule 04.05.2016


Ответы (1)


Это чистый питон. Альтернативная реализация, cKDTree, намного быстрее.

person ev-br    schedule 04.05.2016
comment
Повторная попытка моего кода с cKDTree дает эквивалентную или более высокую производительность по сравнению с cdist. Спасибо! - person TDN169; 04.05.2016