Элементы и индекс самых больших n элементов в списке - PullRequest
1 голос
/ 09 апреля 2019

У меня есть массив:

arr = [23,34,2,55,5,13,44,3]

и я хочу сохранить n самых больших чисел с их индексами.
например, для n = 2 я хочу

[(55,3), (44,6)]

Я не мог найти легкий способ сделать это .. Я только нашел, как получить n больших элементов, используя nlargest или n самых больших индексов, используя argpartition.

Ответы [ 3 ]

2 голосов
/ 09 апреля 2019

Вот решение на основе NumPy:

In [207]: arr
Out[207]: array([23, 34,  2, 55,  5, 13, 44,  3])

# sort array `arr` in increasing order
In [208]: arr_sorted = arr[arr.argsort()]

# slice largest 3 elements
In [209]: largest_3 = arr_sorted[-3:][::-1]

In [210]: largest_3
Out[210]: array([55, 44, 34])

# get the indices that would sort the array `arr` (in increasing order)
In [211]: arr_sorted_idx = arr.argsort()

# grab the largest 3 indices in accordance with [209]/[210]
In [212]: largest_3_idx = arr_sorted_idx[-3:][::-1]

In [213]: largest_3_idx
Out[213]: array([3, 6, 1])

largest_3_idx - индексы трех самых больших элементов в исходном массиве arr.


Если вам нужен результат в виде списка кортежей, используйте:

In [214]: list(zip(largest_3.tolist(), largest_3_idx.tolist()))
Out[214]: [(55, 3), (44, 6), (34, 1)]
2 голосов
/ 09 апреля 2019

Вот сокращенная версия Numpy:

n=3 #number of largest elements to get
a = np.array([23, 34,  2, 55,  5, 13, 44,  3])
idx = a.argsort()[:-n-1:-1] #Use argsort get sorted index and slice backwards
list(zip(a[idx], idx)) #zip and list for tuples

Вывод:

[(55, 3), (44, 6), (34, 1)]

Давайте построим несколько моментов:

import numpy
import perfplot

def sb_numpy(a,n):
    idx = a.argsort()[:-n-1:-1] #Use argsort get sorted index and slice backwards
    return list(zip(a[idx], idx))

def pa_pyth(a,n):
    return list(sorted( ((v,i) for i,v in enumerate(a) ),reverse = True))[:n]


perfplot.show(
    setup=lambda n: numpy.random.randint(0,10e7, n),
    kernels=[
        lambda a: sb_numpy(a,3),
        lambda a: pa_pyth(a,3)
        ],
    labels=['sb_numpy', 'pa_pyth'],
    n_range=[2**k for k in range(15)],
    xlabel='N'
    )

Вывод:

enter image description here

2 голосов
/ 09 апреля 2019

Отказ от ответственности: не простое решение - вы можете комбинировать enumerate, sorted, понимание генератора и нарезку списка:

n = 3
s = list(sorted( ((v,i) for i,v in enumerate([23,34,2,55,5,13,44,3]) ),reverse = True))[:n]

print(s)

Вывод:

 [(55, 3), (44, 6), (34, 1)]

Доку:

Генератор используется для переключения индекса и значения, полученного с помощью перечисления, срезы уменьшают количестворезультатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...