Самый быстрый способ найти n-е наибольшее значение в матричной матрице

Существует множество решений для одного массива, но как насчет матрицы, например:

>>> k
array([[ 35,  48,  63],
       [ 60,  77,  96],
       [ 91, 112, 135]])

Вы можете использовать k.max(), но, конечно, это возвращает только самое высокое значение, 135. Что, если я хочу второй или третий?

Ответы

Ответ 1

Вы можете сгладить матрицу, а затем отсортировать ее:

>>> k = np.array([[ 35,  48,  63],
...        [ 60,  77,  96],
...        [ 91, 112, 135]])
>>> flat=k.flatten()
>>> flat.sort()
>>> flat
array([ 35,  48,  60,  63,  77,  91,  96, 112, 135])
>>> flat[-2]
112
>>> flat[-3]
96

Ответ 2

Как сказано, np.partition должен быть быстрее (не более O (n) времени выполнения):

np.partition(k.flatten(), -2)[-2]

должен вернуть второй по величине элемент. (partition гарантирует, что нумерованный элемент находится в позиции, все элементы до меньше, а все позади больше).

Ответ 3

import numpy as np
a=np.array([[1,2,3],[4,5,6]])
a=a.reshape((a.shape[0])*(a.shape[1]))  # n is the nth largest taken by us
print(a[np.argsort()[-n]])

Ответ 4

Другой способ сделать это, когда повторяющиеся элементы представлены в массиве под рукой. Если у нас есть что-то вроде

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

то вторым по величине элементом будет 3, а не 1.

В качестве альтернативы можно использовать следующий фрагмент:

second_largest = sorted(list(set(a.flatten().tolist())))[-2]

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

Ответ 5

nums = [[ 35,  48,  63],
        [ 60,  77,  96],
        [ 91, 112, 135]]

highs = [max(lst) for lst in nums]
highs[nth]

Ответ 6

Использование уникальной функции - очень чистый способ сделать это, но, вероятно, не самый быстрый:

k = array([[ 35,  48,  63],
           [ 60,  77,  96],
           [ 91, 112, 135]])
i = numpy.unique(k)[-2]

для второго по величине