Вероятно, это немного зависит от размеров a
и k
, но часто наиболее быстрым представляется сочетание partition
с flatnonzero
или where
:
>>> 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
теоретически должен быть как минимум таким же быстрым, но на практике это намного медленнее.