Scikit-learn KDTree query_radius возвращает и количество, и индекс? - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь вернуть и count (количество соседей), и ind (индексы указанных соседей), но я не могу, если я не вызову query_radius дважды, что, хотя вычислительно интенсивно, на самом деле *На 1004 * быстрее для меня в Python, чем итерация и подсчет размеров каждой строки в ind!Это кажется ужасно неэффективным, поэтому мне интересно, есть ли способ просто вернуть их обоих за один вызов?

Я пытался получить доступ к объектам count и ind для tree после вызова query_radius, но он не существует,Там нет эффективного способа сделать это в NumPy, не так ли?

>>> array = np.array([[1,2,3], [2,3,4], [6,2,3]])
>>> tree = KDTree(array)
>>> neighbors = tree.query_radius(array, 1)
>>> tree.ind
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'sklearn.neighbors.kd_tree.KDTree' object has no attribute 'ind'
>>> tree.count
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'sklearn.neighbors.kd_tree.KDTree' object has no attribute 'count'

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Рассмотрите этот набор данных:

array = np.random.random((10**5, 3))*10
tree = KDTree(array)

В вашем вопросе вы можете указать 3 варианта:

1) Дважды позвоните tree.query_radius, чтобы узнать соседей и их количество.

neighbors = tree.query_radius(array, 1)
counts = tree.query_radius(array, 1, count_only=1)

Это занимает 8,347 с.

2) Получить только соседей, а затем получить счет путем их итерации:

neighbors = tree.query_radius(array, 1)
counts = []
for i in range(len(neighbors)):
    counts.append(len(neighbors[i]))

Это значительно быстрее, чем первыйметод и занимает 4.697 с

3) Теперь мы можем улучшить время цикла для расчета counts.

neighbors = tree.query_radius(array, 1)
len_array = np.frompyfunc(len, 1, 1)
counts = len_array(neighbors)

Это быстрый с 4,459 с.

0 голосов
/ 14 сентября 2018

Не знаю, почему вы думаете, что вам нужно сделать это дважды:

a = np.random.rand(100,3)*10
tree = KDTree(a)
neighbors = tree.query_radius(a, 1)

%timeit counts = tree.query_radius(a, 1, count_only = 1)
1000 loops, best of 3: 231 µs per loop

%timeit counts = np.array([arr.size for arr in neighbors])
The slowest run took 5.66 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 22.5 µs per loop

Значительно быстрее просто найти размер объектов массива в neighbors, чем повторить tree.query_radius

...