По сути, вам нужно сделать argsort
, какая реализация вам нужна, зависит от того, хотите ли вы использовать внешние библиотеки (например, NumPy) или если вы хотите остаться чистым Python без зависимостей.
Вопрос, который вы должны задать себе: вы хотите
- индексы, которые будут сортировать массив / список
- индексы, которые элементы будут иметь в отсортированном массиве / списке
К сожалению, пример в вопросе не проясняет, что нужно, потому что оба будут давать один и тот же результат:
>>> arr = np.array([1, 2, 3, 100, 5])
>>> np.argsort(np.argsort(arr))
array([0, 1, 2, 4, 3], dtype=int64)
>>> np.argsort(arr)
array([0, 1, 2, 4, 3], dtype=int64)
Выбор argsort
реализации
Если у вас есть NumPy, вы можете просто использовать функцию numpy.argsort
или метод numpy.ndarray.argsort
.
Реализация без NumPy уже упоминалась в некоторых других ответах, поэтому я просто напомню самое быстрое решение в соответствии с ответом на тестирование здесь
def argsort(l):
return sorted(range(len(l)), key=l.__getitem__)
Получение индексов, которые будут сортировать массив / список
Чтобы получить индексы, которые будут сортировать массив / список, вы можете просто вызвать argsort
массив или список. Я использую версии NumPy здесь, но реализация Python должна давать те же результаты
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(arr)
array([1, 2, 0, 3], dtype=int64)
Результат содержит индексы, необходимые для получения отсортированного массива.
Поскольку отсортированный массив будет массивом [1, 2, 3, 4]
argsorted, он содержит индексы этих элементов в оригинале.
- Наименьшее значение равно
1
индексу 1
в оригинале, поэтому первым элементом результата является 1
.
- Индекс
2
имеет 2
оригинальное значение, поэтому второй элемент результата равен 2
.
3
Имеет индекс 0
в оригинале , так что третий элемент результата 0
.
- Наибольшее значение,
4
и оно по индексу 3
в оригинале, поэтому последний элемент результата 3
.
Получение индексов, которые элементы будут иметь в отсортированном массиве / списке
В этом случае вам необходимо подать заявку argsort
дважды :
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(np.argsort(arr))
array([2, 0, 1, 3], dtype=int64)
В таком случае :
- первый элемент оригинала is
3
, который является третьим по величине значением, поэтому он будет иметь индекс 2
в отсортированном массиве / списке, поэтому первый элемент2
.
- второй элемент оригинала -
1
это наименьшее значение, поэтому он будет иметь индекс 0
в отсортированном массиве / списке, так что второй элемент - 0
.
- третий элемент оригинала -
2
это второе по наименьшему значению, поэтому он будет иметь индекс 1
в отсортированном массиве / списке, так что третий элемент 1
.
- четвертый элемент оригинала -
4
это наибольшее значение, поэтому он будет иметь индекс 3
в отсортированном массиве / списке, так что последний элемент 3
.