2013-05-29 2 views
10

Привет У меня есть массив с X количеством значений в нем. Я хотел бы найти индексы десяти наименьших значений. В этой ссылке они рассчитали максимально эффективно, How to get indices of N maximum values in a numpy array? однако я не могу прокомментировать ссылки, поэтому мне нужно перепросить вопрос.Мне нужны N минимальных (индексных) значений в массиве numpy

Я не уверен, какие индексы мне нужно изменить для достижения минимальных, а не максимальных значений. Это их код

In [1]: import numpy as np 

In [2]: arr = np.array([1, 3, 2, 4, 5]) 

In [3]: arr.argsort()[-3:][::-1] 
Out[3]: array([4, 3, 1]) 

ответ

22

Если вы звоните

arr.argsort()[:3] 

Это даст вам индексы 3 маленьких элементов.

array([0, 2, 1], dtype=int64) 

Так, n, вы должны вызвать

arr.argsort()[:n] 
5

Я не гарантирую, что это будет быстрее, но лучше алгоритм будет опираться на heapq.

import heapq 
indices = heapq.nsmallest(10,np.nditer(arr),key=arr.__getitem__) 

Это должно работать в приблизительно O(N) операций, тогда как с помощью argsort бы O(NlogN) операции. Тем не менее, другой переносится в сильно оптимизированный C, поэтому он все равно может работать лучше. Чтобы точно знать, вам нужно будет запустить некоторые тесты на свои фактические данные.

+0

o да, это тоже работает. Я пытался использовать его раньше, но не хватало его, и он немного усложнился, но теперь он работает:] – astrochris

+0

Работает и для меня. Тем не менее, в моем случае это примерно в 20 раз медленнее, чем чистое решение numpy – embert

+0

Я не думаю, что он работает для поплавков. – darshan

2

Просто не меняйте результаты сортировки.

In [164]: a = numpy.random.random(20) 

In [165]: a 
Out[165]: 
array([ 0.63261763, 0.01718228, 0.42679479, 0.04449562, 0.19160089, 
     0.29653725, 0.93946388, 0.39915215, 0.56751034, 0.873, 
     0.17521395, 0.49573607, 0.84587652, 0.73638224, 0.36303797, 
     0.2150837 , 0.51665416, 0.47111993, 0.79984964, 0.89231776]) 

Сортировка:

In [166]: a.argsort() 
Out[166]: 
array([ 1, 3, 10, 4, 15, 5, 9, 14, 7, 2, 17, 11, 16, 8, 0, 13, 18, 
     12, 19, 6]) 

Первая десятка:

In [168]: a.argsort()[:10] 
Out[168]: array([ 1, 3, 10, 4, 15, 5, 9, 14, 7, 2]) 
10

Поскольку этот вопрос был опубликован, NumPy был обновлен, чтобы включить более быстрый способ выбора самых маленьких элементов из массива с помощью argpartition , Он впервые был включен в Numpy 1.8.

Используя snarly's answer как вдохновение, мы можем быстро найти k=3 мельчайшие элементы:

In [1]: import numpy as np 

In [2]: arr = np.array([1, 3, 2, 4, 5]) 

In [3]: k = 3 

In [4]: ind = np.argpartition(arr, k)[:k] 

In [5]: ind 
Out[5]: array([0, 2, 1]) 

In [6]: arr[ind] 
Out[6]: array([1, 2, 3]) 

Это будет работать в O (п), потому что не нужно делать полный вид. Если вам нужны ваши ответы отсортирован (Примечание: в этом случае выходной массив был отсортирован, но это не гарантировано) вы можете сортировать вывод:

In [7]: sorted(arr[ind]) 
Out[7]: array([1, 2, 3]) 

Это работает на O (п + к лог-к), потому что сортировка выполняется в списке меньших .

Смежные вопросы