Как найти индексы i-го наибольшего элемента n-мерного массива numpy?

Я знаю, как найти индексы максимального элемента n-мерного массива.

Например:

a=np.asarray([[1,7,-4],[9,-11,-17]])

Тогда (источник):

from numpy import unravel_index
unravel_index(a.argmax(), a.shape)

возвращение:

(1, 0)

и действительно, a[1,0] - это 9, который является самым высоким элементом в массиве a, так что у нас все хорошо.


Я также могу выяснить, как найти индексы i-го самого большого элемента одномерного массива numpy (с использованием):

a = np.array([1, 3, 2, 4, 5])

i=3 # we want the third largest element, for example
a.argsort()[-i]

Это возвращает 1, что хорошо, поскольку a[1]=3 действительно является третьим по величине элементом a.


Я хотел бы совместить эти два. Итак, если у меня есть

a=np.asarray([[1,7,-4],[9,-11,-17]])

Я хотел бы получить вывод, сообщающий мне индексы i-го самого большого элемента массива a, например, если i=3, вывод должен быть [0,0], поскольку a[0,0]=1 является i-м (третьим) по величине элементом a.

Как я могу это сделать?

stackoverflow.com/a/9483964/10708112 может помочь.
hqkhan 04.01.2019 23:02

да, проблема в том, что мне всегда нужен максимум (т.е. 1-й по величине), а i-й по величине, чего я не могу сделать с помощью a.argmax ().

zabop 04.01.2019 23:06
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
150
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Это простой способ сделать это.

import numpy as np
i=3
a=np.asarray([[1,7,-4],[9,-11,-17]])
flat=a.flatten()
flat.sort()
print(flat)
print(flat[-i])
i, j = np.where(a == flat[-i])
print(i,j)

Вы можете сгладить, а затем отсортировать его. Он даст вам желаемый результат на основе вашего i-го наибольшего значения, то есть i=3. Если вы введете i = 5, flat[-i] выдаст вам -11.

Это даст мне 1, но как мне получить [0,0]?

zabop 04.01.2019 23:03

да, это действительно дает мне -11, если я = 5. В этом случае я хотел бы иметь [1,1], поскольку [1,1] = - 11 является 5-м по величине элементом массива.

zabop 04.01.2019 23:05

Действительно работает. Спасибо!

zabop 04.01.2019 23:14
Ответ принят как подходящий

Что ж, чтобы получить индекс какого-то самого большого или любого другого, вы можете использовать where:

Добавление к вышеупомянутому ответу webDev:

import numpy as np
i=2

a=np.asarray([[1,7,-4],[9,-11,-17]])

flat=a.flatten()
flat.sort()
tryvalue= flat[-i]

i, j = np.where(a == tryvalue)
print(i,j)

Это даст вам:

[0] [1]

Я имею в виду, что вы можете вносить изменения самостоятельно, как вы хотите, чтобы эти индексы были похожи (кортеж или что-то еще).

да np.where() @Amit

webDev 04.01.2019 23:15

отвечатьАмит Амола отлично подходит. На случай, если кому-то понадобится еще один, я нашел такое решение:

a=np.asarray([[1,7,-4],[9,-11,-17]])
flat=a.flatten()
flat.sort()
i=5

for k, p in enumerate(a):
    for j, q in enumerate(p):
        if q == flat[-i]:
            indices=[k,j]

print(indices)

Отдавать [1, 1], что хорошо.

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

Amit Amola 04.01.2019 23:17

Да, хороший момент, это хорошо работает только для небольших массивов с низкой размерностью.

zabop 05.01.2019 00:46

Вы также можете использовать heapq.nlargest в сглаженном массиве и получить минимум этих самых больших элементов i. В большинстве случаев это должно быть эффективнее сортировки:

import numpy as np
import heapq

a = np.asarray([[1, 7, -4], [9, -11, -17]])
i = 2

ith_largest = min(heapq.nlargest(i, a.flatten()))
x, y = np.where(a == ith_largest)
print(x, y)  # [0] [1]

Другие вопросы по теме