在没有排序的情况下获取numpy数组中N个最大值的索引?

时间:2018-05-25 16:55:28

标签: python numpy

我的问题与此问题非常相似:How to get indices of N maximum values in a numpy array?

但是我想按照我找到它们的顺序获取索引。

让我们将该问题中标记的示例作为正确的解决方案:

import numpy as np
arr = np.array([1, 3, 2, 4, 5])
arr.argsort()[-3:][::-1]

array([4, 3, 1])

我正在寻找的结果应该是:

array([1, 3, 4])

2 个答案:

答案 0 :(得分:2)

使用numpy.argpartition()

k = 3
np.argpartition(arr, len(arr) - k)[-k:]

k索引调整为您需要的任何内容。

注意:返回的索引不保证在"排序顺序" - 只是索引k之后的任何内容都大于排序数组中位置k的值。

注意2:如果确实需要将返回的索引自行排序,则只需在上述命令中添加numpy.sort()

np.sort(np.argpartition(arr, len(arr) - k)[-k:])

numpy.argpartition()比完整sort提供了显着的性能提升,特别是对于大型arr。在上面的示例中,您只对选定的索引(不是全部)进行完整排序。

答案 1 :(得分:2)

这可能取决于ak的大小,但通常最快的似乎是将partitionflatnonzerowhere合并:< / p>

>>> a = np.random.random(10000)
>>> k = 5
>>> 
>>> timeit("np.flatnonzero(a >= np.partition(a, len(a) - k)[len(a) - k])", globals=globals(), number=10000)
0.8328661819687113
>>> timeit("np.sort(np.argpartition(a, len(a) - k)[len(a) - k:])", globals=globals(), number=10000)
1.0577796879806556
>>> np.flatnonzero(a >= np.partition(a, len(a) - k)[len(a) - k])
array([2527, 4299, 5531, 6945, 7174])
>>> np.sort(np.argpartition(a, len(a) - k)[len(a) - k:])
array([2527, 4299, 5531, 6945, 7174])

注1:这突出了间接索引的显着性能成本。

注意2:因为我们只使用pivot元素并丢弃实际分区percentile理论上应该至少同样快,但在实践中它会慢一些。