Numpy argsort-co to robi?

Dlaczego numpy daje taki wynik:

x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()

>[2 3 1 0]

Kiedy bym się tego spodziewał:

[3 2 0 1]

Najwyraźniej brakuje mi zrozumienia tej funkcji.
Author: user1276273, 2013-07-27

7 answers

Zgodnie z dokumentacją

Zwraca indeksy, które posortowałyby tablicę.

  • 2 jest indeksem 0.0.
  • 3 jest indeksem 0.1.
  • 1 jest indeksem 1.41.
  • 0 jest indeksem 1.48.
 85
Author: falsetru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-27 18:48:07

[2, 3, 1, 0] wskazuje, że najmniejszy element znajduje się w indeksie 2, następny najmniejszy w indeksie 3, Następnie indeks 1, a następnie indeks 0.

Istnieje na wiele sposobów aby uzyskać wynik, którego szukasz:

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

Na przykład,

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])

To sprawdza, czy wszystkie dają ten sam wynik:

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))

Te benchmarki IPython %timeit sugerują, że dla dużych tablic using_indexed_assignment jest najszybszy:

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

Dla małych tablic, using_argsort_twice może być szybciej:

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

Zauważ również, że stats.rankdata daje większą kontrolę nad tym, jak obsługiwać elementy o jednakowej wartości.

 28
Author: unutbu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:23

Jako Dokumentacja mówi, argsort:

Zwraca indeksy, które posortowałyby tablicę.

To oznacza, że pierwszy element argsort jest indeksem elementu, który powinien być sortowany jako pierwszy, drugi element jest indeksem elementu, który powinien być drugi, itd.

Wydaje ci się, że potrzebujesz kolejności wartości, która jest dostarczana przez scipy.stats.rankdata. Należy pamiętać, że trzeba pomyśleć o tym, co powinno się stać, jeśli są więzi w szeregów.

 2
Author: BrenBarn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-27 18:48:07

Najpierw uporządkowano tablicę. Następnie Wygeneruj tablicę z początkowym indeksem tablicy.

 0
Author: Rodrigo Saraguro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-29 02:22:25

Po prostu chcę bezpośrednio kontrastować pierwotne zrozumienie OP z rzeczywistą implementacją z kodem.

numpy.argsort jest zdefiniowana tak, że

x[x.argsort()] == numpy.sort(x) # this will be an array of True's

OP początkowo uważał, że została zdefiniowana w taki sposób, że

x == numpy.sort(x)[x.argsort()] # this will not be True
 0
Author: Multihunter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-17 07:33:27

Input:
import numpy jako np
x = np.array([1.48,1.41,0.0,0.1])
x. argsort ().argsort ()

Wyjście:
array([3, 2, 0, 1])

 0
Author: JMpony,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-18 02:41:15

Np.argsort zwraca indeks posortowanej tablicy podany przez 'kind' (który określa typ algorytmu sortowania). Jednak, gdy lista jest używana z np.argmax, zwraca indeks największego elementu na liście. While, np.Sortowanie, sortowanie podanej tablicy, listy.

 0
Author: vivek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-22 08:47:18