Dlaczego numpy podaje ten wynik:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
kiedy spodziewałbym się, że to zrobi:
[3 2 0 1]
Najwyraźniej brakuje mi zrozumienia tej funkcji.
Dlaczego numpy podaje ten wynik:
x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()
>[2 3 1 0]
kiedy spodziewałbym się, że to zrobi:
[3 2 0 1]
Najwyraźniej brakuje mi zrozumienia tej funkcji.
Odpowiedzi:
Zgodnie z dokumentacją
Zwraca indeksy, które posortowałyby tablicę.
2jest indeksem 0.0.3jest indeksem 0.1.1jest indeksem 1.41.0jest indeksem 1.48.a = x.argsort(), drukuj x[a], dostaniemyarray([ 0. , 0.1 , 1.41, 1.48])
[2, 3, 1, 0] wskazuje, że najmniejszy element znajduje się pod indeksem 2, następny najmniejszy element pod indeksem 3, następnie indeks 1, a następnie indeks 0.
Istnieje kilka sposobów uzyskania wyniku, 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 %timeittesty porównawcze IPythona sugerują, że dla dużych tablic using_indexed_assignmentsą najszybsze:
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
W przypadku małych tablic using_argsort_twicemoże być szybsze:
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.rankdatadaje ci to większą kontrolę nad tym, jak obsługiwać elementy o równej wartości.
argsortzwraca indeksy posortowanej tablicy. Indeks posortowanych indeksów to ranga. Oto co argsortpowraca drugie wezwanie .
Jak mówi dokumentacjaargsort :
Zwraca indeksy, które posortowałyby tablicę.
Oznacza to, że pierwszym elementem argsort jest indeks elementu, który powinien być sortowany jako pierwszy, drugi element to indeks elementu, który powinien być drugi itd.
Wydaje się, że chcesz, aby porządek rangi wartości był zapewniony przez scipy.stats.rankdata. Pamiętaj, że musisz pomyśleć o tym, co się stanie, jeśli w szeregach są remisy.
numpy.argsort (a, axis = -1, kind = 'quicksort', order = None)
Zwraca indeksy, które posortowałyby tablicę
Wykonaj pośrednie sortowanie wzdłuż danej osi, używając algorytmu określonego przez słowo kluczowe kind. Zwraca tablicę indeksów o tym samym kształcie, co dane indeksu wzdłuż danej osi w posortowanej kolejności.
Rozważ jeden przykład w Pythonie, mając listę wartości jako
listExample = [0 , 2, 2456, 2000, 5000, 0, 1]
Teraz używamy funkcji argsort:
import numpy as np
list(np.argsort(listExample))
Wynik będzie
[0, 5, 6, 1, 3, 2, 4]
To jest lista indeksów wartości na liście Przykład, jeśli odwzorujesz te indeksy na odpowiednie wartości, otrzymamy następujący wynik:
[0, 0, 1, 2, 2000, 2456, 5000]
(Uważam, że ta funkcja jest bardzo przydatna w wielu miejscach, np. Jeśli chcesz posortować listę / tablicę, ale nie chcesz używać funkcji list.sort () (tj. Bez zmiany kolejności rzeczywistych wartości na liście), możesz użyć tego funkcjonować.)
Więcej informacji można znaleźć pod tym linkiem: https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html
wejście:
import numpy as np
x = np.array ([1.48,1.41,0.0,0.1])
x.argsort (). argsort ()
wyjście:
tablica ([3, 2, 0, 1])
Najpierw zamówiono tablicę. Następnie wygeneruj tablicę z początkowym indeksem tablicy.
Po prostu chcę bezpośrednio porównać oryginalne rozumienie OP z rzeczywistą implementacją za pomocą kodu.
numpy.argsort jest zdefiniowany w taki sposób, że dla tablic 1D:
x[x.argsort()] == numpy.sort(x) # this will be an array of True's
OP początkowo uważał, że został zdefiniowany w taki sposób, że dla tablic 1D:
x == numpy.sort(x)[x.argsort()] # this will not be True
Uwaga: ten kod nie działa w ogólnym przypadku (działa tylko dla 1D), ta odpowiedź ma charakter wyłącznie ilustracyjny.
x[x.argsort()]niekoniecznie jest tym samym, co np.sort(x). W rzeczywistości niekoniecznie ma nawet ten sam kształt. Spróbuj tego z tablicą 2D. Dzieje się tak tylko z tablicami 1D.
[3 2 0 1]byłaby to poprawna odpowiedź?