2014-09-12 16 views
7

Ho bisogno di trovare il modo più rapido per ordinare ogni riga in un dataframe con milioni di righe e circa un centinaio di colonne.Il modo più veloce per ordinare ogni riga in un dataframe panda

Quindi qualcosa di simile:

A B C D 
3 4 8 1 
9 2 7 2 

deve diventare:

A B C D 
8 4 3 1 
9 7 2 2 

In questo momento sto applicando sorta di ogni riga e la costruzione di una nuova riga per riga dataframe. Sto anche facendo un paio di cose in più, meno importanti per ogni riga (quindi perché sto usando i panda e non sono numpy). Potrebbe essere più veloce invece creare una lista di liste e quindi costruire il nuovo dataframe in una volta? O devo andare in cython?

+0

Lo traspone, lo ordina, lo riprende? –

+0

In che modo la trasposizione renderà l'ordinamento più veloce? – Luke

+0

Basta cambiare la "vista" della mappatura ... quindi è ancora necessario fare l'ordinamento, ma si trasforma un 1mx100 in 100x1m nello stesso spazio, ordinarlo, quindi invertendolo, si ha solo la diversa vista sul dati indietro –

risposta

10

penso che avrei fatto questo in NumPy:

In [11]: a = df.values 

In [12]: a.sort(axis=1) # no ascending argument 

In [13]: a = a[:, ::-1] # so reverse 

In [14]: a 
Out[14]: 
array([[8, 4, 3, 1], 
     [9, 7, 2, 2]]) 

In [15]: pd.DataFrame(a, df.index, df.columns) 
Out[15]: 
    A B C D 
0 8 4 3 1 
1 9 7 2 2 

avevo pensato che questo potrebbe funzionare, ma ordina le colonne:

In [21]: df.sort(axis=1, ascending=False) 
Out[21]: 
    D C B A 
0 1 8 4 3 
1 2 7 2 9 

Ah, panda solleva:

In [22]: df.sort(df.columns, axis=1, ascending=False) 
ValueError: When sorting by column, axis must be 0 (rows) 
4

Per aggiungere alla risposta data da @A ndy-Hayden, per fare questo in tutto il frame ... non è proprio sicuro del perché funzioni, ma lo fa. Sembra che non ci sia alcun controllo sull'ordine.

In [97]: A = pd.DataFrame(np.random.randint(0,100,(4,5)), columns=['one','two','three','four','five']) 

    In [98]: A 
    Out[98]: 
    one two three four five 
    0 22 63  72 46 49 
    1 43 30  69 33 25 
    2 93 24  21 56 39 
    3 3 57  52 11 74 

    In [99]: A.values.sort 
    Out[99]: <function ndarray.sort> 

    In [100]: A 
    Out[100]: 
    one two three four five 
    0 22 63  72 46 49 
    1 43 30  69 33 25 
    2 93 24  21 56 39 
    3 3 57  52 11 74 

    In [101]: A.values.sort() 

    In [102]: A 
    Out[102]: 
    one two three four five 
    0 22 46  49 63 72 
    1 25 30  33 43 69 
    2 21 24  39 56 93 
    3 3 11  52 57 74 
    In [103]: A = A.iloc[:,::-1] 

    In [104]: A 
    Out[104]: 
    five four three two one 
    0 72 63  49 46 22 
    1 69 43  33 30 25 
    2 93 56  39 24 21 
    3 74 57  52 11 3 

Spero che qualcuno può spiegare il perché di questo, solo felice che funziona 8)

+0

'A.values' restituisce la rappresentazione numpy di' A', quindi questo 'sort' è solo un tipo pacchiano, fatto sul posto. – ptrj

1

Si potrebbe utilizzare pd.apply.

Eg: 

A = pd.DataFrame(np.random.randint(0,100,(4,5)), columns=['one','two','three','four','five']) 
print (A) 

    one two three four five 
0 2 75  44 53 46 
1 18 51  73 80 66 
2 35 91  86 44 25 
3 60 97  57 33 79 

A = A.apply(np.sort, axis = 1) 
print(A) 

    one two three four five 
0 2 44  46 53 75 
1 18 51  66 73 80 
2 25 35  44 86 91 
3 33 57  60 79 97 

Dal momento che si desidera in ordine decrescente, si può semplicemente moltiplicare il dataframe con -1 e ordinarlo.

A = pd.DataFrame(np.random.randint(0,100,(4,5)), columns=['one','two','three','four','five']) 
A = A * -1 
A = A.apply(np.sort, axis = 1) 
A = A * -1 
Problemi correlati