Ответ 1
Используйте np.argpartition
. Он не сортирует весь массив. Это гарантирует только, что элемент kth
находится в сортированном положении, и все меньшие элементы будут перемещены перед ним. Таким образом, первые элементы k
будут k-наименьшими элементами.
import numpy as np
A = np.array([1, 7, 9, 2, 0.1, 17, 17, 1.5])
k = 3
idx = np.argpartition(A, k)
print(idx)
# [4 0 7 3 1 2 6 5]
Это возвращает наименьшие значения k. Обратите внимание, что они не могут быть отсортированы по порядку.
print(A[idx[:k]])
# [ 0.1 1. 1.5]
Для получения k-наибольших значений используйте
idx = np.argpartition(A, -k)
# [4 0 7 3 1 2 6 5]
A[idx[-3:]]
# [ 9. 17. 17.]
Вот сравнение с np.argsort
, которое также работает, но просто сортирует весь массив, чтобы получить результат.
In [2]: x = np.random.randn(100000)
In [3]: %timeit idx0 = np.argsort(x)[:100]
100 loops, best of 3: 8.26 ms per loop
In [4]: % timeit idx1 = np.argpartition(x, 100)[:100]
1000 loops, best of 3: 721 µs per loop
In [5]: np.alltrue(np.sort(np.argsort(x)[:100]) == np.sort(np.argpartition(x, 100)[:100]))
Out[5]: True