Можно ли использовать argsort в порядке убывания
рассмотрим следующий код:
avgDists = np.array([1, 8, 6, 9, 4])
ids = avgDists.argsort()[:n]
это дает мне показатели n
мельчайшие элементы. Можно ли использовать этот же argsort
в порядке убывания, чтобы получить индексы n
высокие элементы ?
7 ответов:
если вы отрицаете массив, самые низкие элементы становятся самыми высокими элементами и наоборот. Таким образом, индексы
n
высшие элементы:(-avgDists).argsort()[:n]
еще один способ рассуждать об этом, как уже упоминалось в комментарии, это наблюдать, что большие элементы приходят последние в argsort. Итак, вы можете прочитать из хвоста argsort, чтобы найти
n
высшие элементы:avgDists.argsort()[::-1][:n]
оба метода O(n log n) во времени сложности, потому что
argsort
вызов является доминирующим термином здесь. Но второй подход имеет хорошее преимущество: он заменяет O (n) отрицание массива с помощью O (1) срез. Если вы работаете с небольшими массивами внутри циклов, то вы можете получить некоторый прирост производительности, избегая этого отрицания, и если вы работаете с огромными массивами, то вы можете сэкономить на использовании памяти, потому что отрицание создает копию всего массива.обратите внимание, что эти методы не всегда дают эквивалентные результаты: если требуется стабильная реализация сортировки
argsort
, например, передавая аргумент ключевого словаkind='mergesort'
, то первая стратегия сохранит стабильность сортировки, но вторая стратегия нарушит стабильность (т. е. позиции равных элементов будут перевернуты).
так же, как Python, в этом
[::-1]
реверсирует массив, возвращенныйargsort()
и[:n]
дает последние n элементов:>>> avgDists=np.array([1, 8, 6, 9, 4]) >>> n=3 >>> ids = avgDists.argsort()[::-1][:n] >>> ids array([3, 1, 2])
преимущество этого метода заключается в том, что
ids
это посмотреть из avgDists:>>> ids.flags C_CONTIGUOUS : False F_CONTIGUOUS : False OWNDATA : False WRITEABLE : True ALIGNED : True UPDATEIFCOPY : False
(значение' OWNDATA ' False указывает, что это представление, а не копия)
другой способ сделать это что-то вроде:
(-avgDists).argsort()[:n]
проблема в том, что способ, которым это работает, заключается в создании негатива каждого элемент в массиве:
>>> (-avgDists) array([-1, -8, -6, -9, -4])
и создает копию для этого:
>>> (-avgDists_n).flags['OWNDATA'] True
так что если вы время каждого, даже с этим очень маленьким набором данных:
>>> import timeit >>> timeit.timeit('(-avgDists).argsort()[:3]', setup="from __main__ import avgDists") 4.2879798610229045 >>> timeit.timeit('avgDists.argsort()[::-1][:3]', setup="from __main__ import avgDists") 2.8372560259886086
метод просмотра существенно быстрее
вы можете создать копию массива, а затем умножить каждый элемент с -1.
В результате раньше самые большие элементы стали бы самыми маленькими.
Индексами n наименьших элементов в копии являются n наибольших элементов в оригинале.
вы можете использовать флип команды
numpy.flipud()
илиnumpy.fliplr()
чтобы получить индексы, в порядке убывания после сортировки с помощью . Это то, что я обычно делаю.
вместо
np.argsort
вы могли бы использоватьnp.argpartition
- если вам нужны только индексы самых низких / самых высоких n элементов.это не требует сортировки всего массива, но только часть, которая вам нужна, но обратите внимание, что" порядок внутри вашего раздела " не определен, поэтому, хотя он дает правильные индексы, они могут быть неправильно упорядочены:
>>> avgDists = [1, 8, 6, 9, 4] >>> np.array(avgDists).argpartition(2)[:2] # indices of lowest 2 items array([0, 4], dtype=int64) >>> np.array(avgDists).argpartition(-2)[-2:] # indices of highest 2 items array([1, 3], dtype=int64)
С вас пример:
avgDists = np.array([1, 8, 6, 9, 4])
получить индексы n максимальных значений:
ids = np.argpartition(avgDists, -n)[-n:]
сортировать их в порядке убывания:
ids = ids[np.argsort(avgDists[ids])[::-1]]
получить результаты (для n=4):
>>> avgDists[ids] array([9, 8, 6, 4])
другой способ-использовать только '-' в аргументе для argsort, как в : "df[np.argsort (- df[:, 0])]", при условии, что DF является фреймом данных, и вы хотите отсортировать его по первому столбцу (представленному номером столбца '0'). Измените имя столбца соответствующим образом. Конечно, столбец должен быть числовым.