Чому немічний дає такий результат:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
коли я очікував би це зробити:
[3 2 0 1]
Очевидно, що моє розуміння функції не вистачає.
Чому немічний дає такий результат:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
коли я очікував би це зробити:
[3 2 0 1]
Очевидно, що моє розуміння функції не вистачає.
Відповіді:
Відповідно до документації
Повертає індекси, які б сортували масив.
2
є індексом 0.0
.3
є індексом 0.1
.1
є індексом 1.41
.0
є індексом 1.48
.a = x.argsort()
, друк x[a]
, ми отримаємоarray([ 0. , 0.1 , 1.41, 1.48])
[2, 3, 1, 0]
означає, що найменший елемент знаходиться в індексі 2, наступний найменший в індексі 3, потім індекс 1, потім індекс 0.
Існує кілька способів отримати результат, який ви шукаєте:
import numpy as np
import scipy.stats as stats
def using_indexed_assignment(x):
"https://stackoverflow.com/a/5284703/190597 (Sven Marnach)"
result = np.empty(len(x), dtype=int)
temp = x.argsort()
result[temp] = np.arange(len(x))
return result
def using_rankdata(x):
return stats.rankdata(x)-1
def using_argsort_twice(x):
"https://stackoverflow.com/a/6266510/190597 (k.rooijers)"
return np.argsort(np.argsort(x))
def using_digitize(x):
unique_vals, index = np.unique(x, return_inverse=True)
return np.digitize(x, bins=unique_vals) - 1
Наприклад,
In [72]: x = np.array([1.48,1.41,0.0,0.1])
In [73]: using_indexed_assignment(x)
Out[73]: array([3, 2, 0, 1])
Це перевіряє, чи всі вони дають однаковий результат:
x = np.random.random(10**5)
expected = using_indexed_assignment(x)
for func in (using_argsort_twice, using_digitize, using_rankdata):
assert np.allclose(expected, func(x))
Ці %timeit
орієнтири IPython передбачають, що для великих масивів using_indexed_assignment
найшвидший:
In [50]: x = np.random.random(10**5)
In [66]: %timeit using_indexed_assignment(x)
100 loops, best of 3: 9.32 ms per loop
In [70]: %timeit using_rankdata(x)
100 loops, best of 3: 10.6 ms per loop
In [56]: %timeit using_argsort_twice(x)
100 loops, best of 3: 16.2 ms per loop
In [59]: %timeit using_digitize(x)
10 loops, best of 3: 27 ms per loop
Для малих масивів using_argsort_twice
може бути швидше:
In [78]: x = np.random.random(10**2)
In [81]: %timeit using_argsort_twice(x)
100000 loops, best of 3: 3.45 µs per loop
In [79]: %timeit using_indexed_assignment(x)
100000 loops, best of 3: 4.78 µs per loop
In [80]: %timeit using_rankdata(x)
100000 loops, best of 3: 19 µs per loop
In [82]: %timeit using_digitize(x)
10000 loops, best of 3: 26.2 µs per loop
Зауважте також, що stats.rankdata
ви надаєте більше контролю над тим, як обробляти елементи, що мають однакове значення.
argsort
повертає індекси відсортованого масиву. Індекс відсортованих індексів - це ранг. Це те, що argsort
повертається другий дзвінок .
У документації йдеться, argsort
:
Повертає індекси, які б сортували масив.
Це означає, що перший елемент арґсорту - це індекс елемента, який слід впорядкувати перший, другий - індекс елемента, який повинен бути другим тощо.
Те, що вам здається, хочеться - це порядок ранжування значень, який забезпечується scipy.stats.rankdata
. Зауважте, що вам потрібно подумати про те, що має статися, якщо у званнях є зв’язки.
numpy.argsort (a, вісь = -1, kind = 'quicksort', order = None)
Повертає індекси, які б сортували масив
Виконайте непряме сортування по заданій осі, використовуючи алгоритм, визначений ключовим словом типу. Він повертає масив індексів тієї ж форми, що і дані індексу вздовж даної осі, у відсортованому порядку.
Розглянемо один приклад в python, що має список значень як
listExample = [0 , 2, 2456, 2000, 5000, 0, 1]
Тепер ми використовуємо функцію argsort:
import numpy as np
list(np.argsort(listExample))
Вихід буде
[0, 5, 6, 1, 3, 2, 4]
Це перелік індексів значень у listExample, якщо ви порівнюєте ці індекси з відповідними значеннями, то ми отримаємо результат наступним чином:
[0, 0, 1, 2, 2000, 2456, 5000]
(Я вважаю цю функцію дуже корисною у багатьох місцях, наприклад, якщо ви хочете сортувати список / масив, але не хочете використовувати функцію list.sort () (тобто без зміни порядку фактичних значень у списку), ви можете використовувати цю функцію функція.)
Більш детальну інформацію можна знайти за цим посиланням: https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html
вхід:
імпорт numpy як np
x = np.array ([1.48,1.41,0.0,0.1])
x.argsort (). argsort ()
вихід:
масив ([3, 2, 0, 1])
По-перше, було замовлено масив. Потім генерують масив з початковим індексом масиву.
Просто хочу прямо протиставити початкове розуміння ОП проти фактичної реалізації з кодом.
numpy.argsort
визначається таким чином, що для 1D масивів:
x[x.argsort()] == numpy.sort(x) # this will be an array of True's
OP спочатку вважав, що він визначений таким чином, що для 1D масивів:
x == numpy.sort(x)[x.argsort()] # this will not be True
Примітка: Цей код не працює в загальному випадку (працює лише для 1D), ця відповідь є виключно для ілюстрації.
x[x.argsort()]
не обов'язково те саме, що np.sort(x)
. Насправді це не обов’язково навіть однакової форми. Спробуйте це з 2D-масивом. Це трапляється лише для роботи з 1D-масивами.
[3 2 0 1]
що це буде правильна відповідь?