Как получить индексы N максимальных значений в массиве NumPy? - PullRequest
385 голосов
/ 02 августа 2011

NumPy предлагает способ получить индекс максимального значения массива через np.argmax.

Мне бы хотелось сделать то же самое, но возвращать индексы максимальных значений N.

Например, если у меня есть массив, [1, 3, 2, 4, 5], function(array, n=3) вернет индексы [4, 3, 1], которые соответствуют элементам [5, 4, 3].

Ответы [ 15 ]

2 голосов
/ 25 января 2018

Метод np.argpartition возвращает только k самых больших индексов, выполняет локальную сортировку и работает быстрее, чем np.argsort (выполнение полной сортировки), когда массив довольно большой.Но возвращаемые индексы НЕ в порядке возрастания / убывания .Скажем, на примере:

Enter image description here

Мы можем видеть, что если вы хотите строгий порядок старших индексов в порядке возрастания, np.argpartition не вернет то, чтовы хотите.

Помимо выполнения сортировки вручную после np.argpartition, мое решение заключается в использовании PyTorch, torch.topk, инструмента для построения нейронных сетей, предоставляющего API-интерфейсы, подобные NumPy, споддержка как CPU, так и GPU.Это так же быстро, как NumPy с MKL, и предлагает повышение GPU, если вам нужны большие матричные / векторные вычисления.

Строгий индекс индексов k для восходящих и нисходящих верхних значений будет:

Enter image description here

Обратите внимание, что torch.topk принимает тензор резака и возвращает как верхние k-значения, так и верхние k-индексы типа torch.Tensor.Как и в случае с np, torch.topk также принимает аргумент оси, так что вы можете обрабатывать многомерные массивы / тензоры.

2 голосов
/ 17 апреля 2016

Использование:

from operator import itemgetter
from heapq import nlargest
result = nlargest(N, enumerate(your_list), itemgetter(1))

Теперь список result будет содержать N кортежей (index, value), где value развернуто.

1 голос
/ 16 июня 2018

Ниже приведен очень простой способ увидеть максимальные элементы и их позиции.Здесь axis - домен;axis = 0 означает максимальное число по столбцам, а axis = 1 означает максимальное число по строкам для 2D-случая.А для более высоких измерений это зависит от вас.

M = np.random.random((3, 4))
print(M)
print(M.max(axis=1), M.argmax(axis=1))
0 голосов
/ 25 апреля 2018

Я думаю, что наиболее эффективный способ - это итерация по массиву вручную и сохранение минимальной кучи размера k, как упоминали другие.

И я также придумала метод грубой силы:

top_k_index_list = [ ]
for i in range(k):
    top_k_index_list.append(np.argmax(my_array))
    my_array[top_k_index_list[-1]] = -float('inf')

Установите для наибольшего элемента большое отрицательное значение после того, как вы используете argmax для получения его индекса.И тогда следующий вызов argmax вернет второй по величине элемент.И вы можете записать первоначальное значение этих элементов и восстановить их, если хотите.

0 голосов
/ 12 января 2018

Я нашел наиболее интуитивно понятным использование np.unique.

Идея состоит в том, что уникальный метод возвращает индексы входных значений.Затем из максимального уникального значения и признаков можно воссоздать положение исходных значений.

...