Мне нужны N минимальных (индексных) значений в массиве numpy
Hi у меня есть массив с количеством значений X в нем я хотел бы найти индексы десяти наименьших значений. В этой ссылке они рассчитали максимально эффективно, Как получить индексы 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])
4 ответов
если вы называете
arr.argsort()[:3]
это даст вам индексы 3 самых маленьких элементов.
array([0, 2, 1], dtype=int64)
так, для n
, вам необходимо позвонить
arr.argsort()[:n]
поскольку этот вопрос был опубликован, numpy обновился, чтобы включить более быстрый способ выбора наименьших элементов из массива с помощью argpartition
. Он был впервые включен в Numpy 1.8.
используя запутанно все!--6--> как вдохновение, мы можем быстро найти 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 (n) раз, потому что ему не нужно делать полную сортировку. Если вам нужны ответы отсортированы (Примечание: в этом случае выходной массив был в отсортированном порядке, но это не гарантируется) вы можете отсортировать вывод:
In [7]: sorted(arr[ind])
Out[7]: array([1, 2, 3])
это выполняется на O (N + K log k), потому что сортировка происходит на меньшем список вывода.
Я не гарантирую, что это будет быстрее, но алгоритм будет полагаться на heapq
.
import heapq
indices = heapq.nsmallest(10,np.nditer(arr),key=arr.__getitem__)
Это должно работать примерно через O(N)
операции при использовании argsort
примет O(NlogN)
операции. Однако другой выталкивается в высоко оптимизированный C, поэтому он все равно может работать лучше. Чтобы знать наверняка, вам нужно будет выполнить некоторые тесты на ваших фактических данных.
просто не отменяйте результаты сортировки.
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.33210873,
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])