По сути, вам нужно сделать 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.