Dlaczego pomyślałeś, że [3 2 0 1]byłaby to poprawna odpowiedź?
zwol
9
Po prostu miałem odwrotne rozumienie wyniku. To znaczy, jeśli weźmiesz pierwszy element x, powinien on znajdować się na pozycji 3 posortowanej tablicy i tak dalej.
user1276273
26
Twój sposób myślenia ma sens, miałem dokładnie to samo pytanie
adrienlucca.wordpress.com
2
[3 2 0 1] - to ranking wartości, nie otrzymujesz rzeczywistych wskaźników.
Lahiru Karunaratne
Wystarczy pamiętać, że dane wyjściowe wskazują lokalizacje w oryginalnej tablicy, podczas gdy myślisz, że w posortowanej tablicy. Oznacza to, że dane wyjściowe [0] to indeks, w którym najmniejszy element oryginalnej tablicy wejściowej lokalizuje i wyprowadza [-1] dla największego elementu.
[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 npimport scipy.stats as statsdef 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 resultdef using_rankdata(x):return stats.rankdata(x)-1def 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])
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 loopIn[70]:%timeit using_rankdata(x)100 loops, best of 3:10.6 ms per loopIn[56]:%timeit using_argsort_twice(x)100 loops, best of 3:16.2 ms per loopIn[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 loopIn[79]:%timeit using_indexed_assignment(x)100000 loops, best of 3:4.78µs per loopIn[80]:%timeit using_rankdata(x)100000 loops, best of 3:19µs per loopIn[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.
Czy możesz dodać wyjaśnienie, dlaczego dwukrotne zastosowanie argsort () daje nam rangę?
Phani,
1
@Phani: argsortzwraca indeksy posortowanej tablicy. Indeks posortowanych indeksów to ranga. Oto co argsortpowraca drugie wezwanie .
unutbu
2
Pierwszy argument argsort zwraca permutację (która po zastosowaniu do danych posortowałaby ją). Kiedy argument argsort jest stosowany do (tej lub dowolnej) permutacji, zwraca permutację odwrotną (jeśli te dwie permutacje zostaną zastosowane względem siebie w dowolnej kolejności, wynikiem jest Identity). Druga permutacja zastosowana do posortowanej tablicy danych dałaby nieposortowaną tablicę danych, tj. Jest to ranga.
Alex C
1
Rozumiem. W końcu to zrozumiałem! Zwraca tablicę, której zawartość jest indeksami oryginalnej tablicy w posortowanej kolejności.
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.
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ć.)
Chociaż ten fragment kodu może być rozwiązaniem, dołączenie wyjaśnienia naprawdę pomaga poprawić jakość Twojego posta. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a osoby te mogą nie znać powodów, dla których zaproponowałeś kod.
Peacetype
0
Najpierw zamówiono tablicę. Następnie wygeneruj tablicę z początkowym indeksem tablicy.
np.argsort zwraca indeks posortowanej tablicy podany przez 'rodzaj' (który określa typ algorytmu sortowania). Jednak gdy lista jest używana z np.argmax, zwraca indeks największego elementu na liście. Natomiast np.sort sortuje podaną tablicę list.
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.
Nathan
Wydaje mi się, że to niepotrzebnie pedantyczne. Pytanie dotyczy tablic 1D. Ma to na celu raczej zrozumienie, na czym polegała różnica, niż użycie dosłownego kodu. Ponadto, gdy masz tablicę 2D, nie jest nawet jasne, jakiego rodzaju sortowania chcesz. Chcesz globalnego sortowania? Jeśli nie, którą oś należy sortować? Niezależnie od tego, dodałem zastrzeżenie.
Multihunter
0
Zwraca indeksy zgodnie z podanymi indeksami tablicy, [1.48,1.41,0.0,0.1]czyli:
0.0jest pierwszym elementem w indeksie [2].
0.1jest drugim elementem w indeksie [3].
1.41to trzeci element w indeksie [1].
1.48to czwarty element w indeksie [0]. Wynik:
[3 2 0 1]
byłaby to poprawna odpowiedź?Odpowiedzi:
Zgodnie z dokumentacją
2
jest indeksem0.0
.3
jest indeksem0.1
.1
jest indeksem1.41
.0
jest indeksem1.48
.źródło
a = x.argsort()
, drukujx[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:
Na przykład,
To sprawdza, czy wszystkie dają ten sam wynik:
Te
%timeit
testy porównawcze IPythona sugerują, że dla dużych tablicusing_indexed_assignment
są najszybsze:W przypadku małych tablic
using_argsort_twice
może być szybsze:Zauważ również, że
stats.rankdata
daje ci to większą kontrolę nad tym, jak obsługiwać elementy o równej wartości.źródło
argsort
zwraca indeksy posortowanej tablicy. Indeks posortowanych indeksów to ranga. Oto coargsort
powraca drugie wezwanie .Jak mówi dokumentacja
argsort
: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.źródło
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
Teraz używamy funkcji argsort:
Wynik będzie
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:
(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
źródło
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])
źródło
Najpierw zamówiono tablicę. Następnie wygeneruj tablicę z początkowym indeksem tablicy.
źródło
np.argsort zwraca indeks posortowanej tablicy podany przez 'rodzaj' (który określa typ algorytmu sortowania). Jednak gdy lista jest używana z np.argmax, zwraca indeks największego elementu na liście. Natomiast np.sort sortuje podaną tablicę list.
źródło
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:OP początkowo uważał, że został zdefiniowany w taki sposób, że dla tablic 1D:
Uwaga: ten kod nie działa w ogólnym przypadku (działa tylko dla 1D), ta odpowiedź ma charakter wyłącznie ilustracyjny.
źródło
x[x.argsort()]
niekoniecznie jest tym samym, conp.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.Zwraca indeksy zgodnie z podanymi indeksami tablicy,
[1.48,1.41,0.0,0.1]
czyli:0.0
jest pierwszym elementem w indeksie [2].0.1
jest drugim elementem w indeksie [3].1.41
to trzeci element w indeksie [1].1.48
to czwarty element w indeksie [0]. Wynik:źródło