Cum pot sorta un tablou în NumPy de cel mai inalt coloana?
De exemplu,
a = array([[9, 2, 3],
[4, 5, 6],
[7, 0, 5]])
Am'd place să sortați rânduri de-a doua coloană, astfel că mă întorc:
array([[7, 0, 5],
[9, 2, 3],
[4, 5, 6]])
Cred că acest lucru funcționează: o[o[:,1].argsort()]`
Acest lucru indică coloana a doua din " a " și sortare se bazează pe ea în mod corespunzător.
@steve's este de fapt cel mai elegant mod de a face aceasta.
Pentru "corect" mod de a vedea ordinea de cuvinte cheie argument al numpy.ndarray.sorta
Cu toate acestea,'ll nevoie pentru a vizualiza matrice ca o matrice cu câmpuri (o matrice structurate).
"corect" drumul este destul de urât dacă ai n't inițial defini matrice cu câmpuri...
Ca un scurt exemplu, pentru a sorta și să se întoarcă o copie:
In [1]: import numpy as np
In [2]: a = np.array([[1,2,3],[4,5,6],[0,0,1]])
In [3]: np.sort(a.view('i8,i8,i8'), order=['f1'], axis=0).view(np.int)
Out[3]:
array([[0, 0, 1],
[1, 2, 3],
[4, 5, 6]])
La fel se în-loc:
In [6]: a.view('i8,i8,i8').sort(order=['f1'], axis=0) #<-- returns None
In [7]: a
Out[7]:
array([[0, 0, 1],
[1, 2, 3],
[4, 5, 6]])
@Steve's este într-adevăr cel mai elegant mod de a face asta, din câte știu...
Singurul avantaj al acestei metode este că "pentru" argument este o listă de câmpuri pentru a comanda de căutare de. De exemplu, aveți posibilitatea să sortați după coloana a doua, apoi a treia coloană, apoi prima coloană prin furnizarea de comand=['f1','f2','f0'].
Puteți sorta pe coloane multiple ca pe Steve Tjoa's metoda prin utilizarea unui stabilă fel ca mergesort de sortare și a indicilor de la cel mai puțin semnificativ pentru cele mai importante coloane:
a = a[a[:,2].argsort()] # First sort doesn't need to be stable.
a = a[a[:,1].argsort(kind='mergesort')]
a = a[a[:,0].argsort(kind='mergesort')]
Această felul de coloana 0, apoi 1, apoi 2.
De Python documentația wiki, cred că poți să faci:
a = ([[1, 2, 3], [4, 5, 6], [0, 0, 1]]);
a = sorted(a, key=lambda a_entry: a_entry[1])
print a
De ieșire este:
[[[0, 0, 1], [1, 2, 3], [4, 5, 6]]]
În cazul în care cineva vrea să facă uz de sortare la o parte critică a programelor lor de aici's o comparație de performanță pentru diferite propuneri:
import numpy as np
table = np.random.rand(5000, 10)
%timeit table.view('f8,f8,f8,f8,f8,f8,f8,f8,f8,f8').sort(order=['f9'], axis=0)
1000 loops, best of 3: 1.88 ms per loop
%timeit table[table[:,9].argsort()]
10000 loops, best of 3: 180 µs per loop
import pandas as pd
df = pd.DataFrame(table)
%timeit df.sort_values(9, ascending=True)
1000 loops, best of 3: 400 µs per loop
Deci, se pare ca indexarea cu argsort este cea mai rapidă metodă atât de departe...
De NumPy mailing list, aici's o altă soluție:
>>> a
array([[1, 2],
[0, 0],
[1, 0],
[0, 2],
[2, 1],
[1, 0],
[1, 0],
[0, 0],
[1, 0],
[2, 2]])
>>> a[np.lexsort(np.fliplr(a).T)]
array([[0, 0],
[0, 0],
[0, 2],
[1, 0],
[1, 0],
[1, 0],
[1, 0],
[1, 2],
[2, 1],
[2, 2]])
Am avut o problema asemanatoare.
Problema Mea:
Vreau să calculeze un SVD și au nevoie pentru a sorta mea proprii, în ordine descrescătoare. Dar vreau să păstrez mapare între valorile proprii și vectorii proprii. Mea valori proprii au fost în primul rând și vector propriu corespunzător de mai jos în aceeași coloană.
Deci, vreau pentru a sorta un tablou bidimensional coloană de la primul rând, în ordine descrescătoare.
Soluția Mea
a = a[::, a[0,].argsort()[::-1]]
Deci, cum face acest lucru?
o[0,]
este doar primul rând vreau să sortați.
Acum am folosi argsort pentru a obține ordinea indicilor.
Eu folosesc [::-1]
pentru că am nevoie de ordine descrescătoare.
În cele din urmă am folosit o[::, ...]
pentru a obține o vedere cu coloanele în ordinea corectă.
Un pic mai complicat lexsort
exemplu - descrescătoare pe 1 coloană, în al doilea rând ascendent pe a 2-a. Trucuri cu lexsortsunt care se sortează pe rânduri (de aici
.T`), și dă prioritate la ultimul.
In [120]: b=np.array([[1,2,1],[3,1,2],[1,1,3],[2,3,4],[3,2,5],[2,1,6]])
In [121]: b
Out[121]:
array([[1, 2, 1],
[3, 1, 2],
[1, 1, 3],
[2, 3, 4],
[3, 2, 5],
[2, 1, 6]])
In [122]: b[np.lexsort(([1,-1]*b[:,[1,0]]).T)]
Out[122]:
array([[3, 1, 2],
[3, 2, 5],
[2, 1, 6],
[2, 3, 4],
[1, 1, 3],
[1, 2, 1]])
Aici este o altă soluție, având în vedere toate coloane (mai compact mod de a J. J's de răspuns);
ar=np.array([[0, 0, 0, 1],
[1, 0, 1, 0],
[0, 1, 0, 0],
[1, 0, 0, 1],
[0, 0, 1, 0],
[1, 1, 0, 0]])
Fel cu lexsort,
ar[np.lexsort(([ar[:, i] for i in range(ar.shape[1]-1, -1, -1)]))]
Ieșire:
array([[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 1, 0, 0],
[1, 0, 0, 1],
[1, 0, 1, 0],
[1, 1, 0, 0]])