有效地查找Python数组/列表中N个最大元素的索引

Wil*_*uks 19 python performance numpy

如果这是一个重复的问题,我很抱歉,我查找了这些信息,但仍然无法找到它.

是否可以通过非常有效地使用递减顺序的N个最大元素的索引来排列numpy数组(或python列表)?

例如,数组:

a = array([4, 1, 0, 8, 5, 2])
Run Code Online (Sandbox Code Playgroud)

降序中最大元素的索引将给出(考虑N = 6,包括所有元素):

8 - > 3

5 - > 4

4 - > 0

2 - > 5

1 - > 1

0 - > 2

result = [3, 4, 0, 5, 1, 2]
Run Code Online (Sandbox Code Playgroud)

我知道如何使用一些有点愚蠢的方法来制作它(比如对数组进行排序并搜索其索引中的每个N个数字),但我想知道是否有任何有效的库,如瓶颈或heapq,或者可能是pythonic方法这非常快.我必须在几个阵列中应用它,每个阵列有300k元素,这就是性能问题的原因.

提前致谢!

UPDATE

我读了答案并决定使用300k的随机整数来计算它们,结果如下:

解决方案1: sorted(range(len(a)), key=lambda i:a[i]) 时间: 230毫秒

解决方案2: heapq.nlargest(len(a), zip(a, itertools.count())) 时间: 396毫秒

解决方案3: heapq.nlargest(len(a), enumerate(a), key=operator.itemgetter(1)) 时间: 864毫秒

解决方案4: def f(a,N): return np.argsort(a)[::-1][:N] (N = len(a)) 时间:104毫秒

非常感谢快速和非常好的答案!

Jos*_*del 20

你看过内置的numpy argsort方法吗?:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html

我可以使用该方法在我的机器上在大约29毫秒内对一个包含300,000个随机浮点数的数组进行排序.

def f(a,N):
    return np.argsort(a)[::-1][:N]
Run Code Online (Sandbox Code Playgroud)


ins*_*get 11

L = [4, 1, 0, 8, 5, 2]
sorted(range(len(L)), key=lambda i:L[i])
Run Code Online (Sandbox Code Playgroud)

  • `key = L .__ getitem__`是另一种选择(在某些情况下可能会快一些). (2认同)

Gar*_*tty 5

你可以用来heapq轻松地做到这一点:

>>> heapq.nlargest(3, zip(a, itertools.count()))
[(8, 3), (5, 4), (4, 5)]
Run Code Online (Sandbox Code Playgroud)

元组通过对第一个值进行排序,然后对第二个值进行排序等等...这意味着我们可以简单地对元组进行(value, index)排序和排序,为我们提供值的索引(也给出了值,但我们可以轻松地抛出这些离开).

我正在使用zip()并且itertools.count()作为枚举给我们错误的顺序,因此它们将按索引排序,而不是按值排序.或者,您也可以这样做((value, index) for index, value in enumerate(a)),但我觉得不太清楚.

另一种选择是给出一把钥匙heapq.nlargest(3, enumerate(a), key=operator.itemgetter(1)).