2013-07-12 13 views
44

Ho la seguente struttura dei dati:Come ordinare il frame dei dati dei panda usando i valori di più colonne?

df = pandas.DataFrame([{'c1':3,'c2':10},{'c1':2, 'c2':30},{'c1':1,'c2':20},{'c1':2,'c2':15},{'c1':2,'c2':100}]) 

o, in forma leggibile:

c1 c2 
0 3 10 
1 2 30 
2 1 20 
3 2 15 
4 2 100 

I seguenti cernita comando funziona come previsto:

df.sort(['c1','c2'], ascending=False) 

uscita:

c1 c2 
0 3 10 
4 2 100 
1 2 30 
3 2 15 
2 1 20 

Ma il seguente comando:

df.sort(['c1','c2'], ascending=[False,True]) 

risultati in

c1 c2 
2 1 20 
3 2 15 
1 2 30 
4 2 100 
0 3 10 

e questo non è quello che mi aspetto. Mi aspetto di avere i valori nella prima colonna ordinati dal più grande al più piccolo, e se ci sono valori identici nella prima colonna, ordine dai valori ascendenti dalla seconda colonna.

Qualcuno sa perché non funziona come previsto?

AGGIUNTO

Si tratta di copia-incolla:

>>> df.sort(['c1','c2'], ascending=[False,True]) 
    c1 c2 
2 1 20 
3 2 15 
1 2 30 
4 2 100 
0 3 10 
+0

Quale versione di panda e numpy stai usando? –

risposta

42

Il codice funziona per me.

>>> import pandas 
>>> df = pandas.DataFrame([{'c1':3,'c2':10},{'c1':2, 'c2':30},{'c1':1,'c2':20},{'c1':2,'c2':15},{'c1':2,'c2':100}]) 
>>> df.sort(['c1','c2'], ascending=[False,True]) 
    c1 c2 
0 3 10 
3 2 15 
1 2 30 
4 2 100 
2 1 20 

Hai Incolla come è?

>>> df.sort(['c1','c2'], ascending=[True,True]) 
    c1 c2 
2 1 20 
3 2 15 
1 2 30 
4 2 100 
0 3 10 

UPDATEDataFrame.sort è obsoleto; utilizzare DataFrame.sort_values.

>>> df.sort(['c1','c2'], ascending=[False,True]) 
__main__:1: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....) 
    c1 c2 
0 3 10 
3 2 15 
1 2 30 
4 2 100 
2 1 20 
>>> df.sort_values(['c1','c2'], ascending=[False,True]) 
    c1 c2 
0 3 10 
3 2 15 
1 2 30 
4 2 100 
2 1 20 
+0

Suggerimento: ordine inverso con originale in basso, aggiornamento in alto. Leggendo dall'alto verso il basso ho provato il primo blocco e mi sono chiesto perché non ha funzionato, essendo doppiamente confuso da "funziona per me" e "hai incollato così com'è" (sicuramente è stata colpa mia!). Poi ho fatto scorrere e ho visto l'aggiornamento ... – Hendy

2

Se si sta scrivendo questo codice come un file di script, allora si dovrà scrivere in questo modo:

df = df.sort(['c1','c2'], ascending=[False,True]) 
21

L'utilizzo di sort può causare messaggio di avviso. Vedi discussione github. Così si potrebbe desiderare di utilizzare sort_values, docs here

Allora il tuo codice può apparire come segue:

df = df.sort_values(by=['c1','c2'], ascending=[False,True]) 
+0

Sto ricevendo avvisi altrimenti '/Applications/anaconda/lib/python2.7/site-packages/spyderlib/widgets/externalshell/start_ipython_kernel.py:1: FutureWarning: sort (columns = ....) è deprecato, usa sort_values ​​(by = .....) ' – abhiieor

+0

@patapouf_ai No,' sort' è ora deprecato – oulenz

1

Ho trovato questo per essere veramente utile:

df = pd.DataFrame({'A' : range(0,10) * 2, 'B' : np.random.randint(20,30,20)}) 

# A ascending, B descending 
df.sort(**skw(columns=['A','-B'])) 

# A descending, B ascending 
df.sort(**skw(columns=['-A','+B'])) 

Si noti che a differenza dello standard columns=,ascending= argomenti, qui i nomi delle colonne e il loro ordine sono nello stesso posto. Di conseguenza il tuo codice diventa molto più facile da leggere e mantenere.

Nota la chiamata effettiva al .sort è invariato, skw (s ort kw args) è solo una piccola funzione di supporto che analizza le colonne e restituisce i soliti columns= e ascending= parametri per voi. Passa qualsiasi altro tipo di kwarg come faresti normalmente. Copia/incolla il seguente codice in es. il tuo locale utils.py quindi dimenticarlo e usarlo come sopra.

# utils.py (or anywhere else convenient to import) 
def skw(columns=None, **kwargs): 
    """ get sort kwargs by parsing sort order given in column name """ 
    # set default order as ascending (+) 
    sort_cols = ['+' + col if col[0] != '-' else col for col in columns] 
    # get sort kwargs 
    columns, ascending = zip(*[(col.replace('+', '').replace('-', ''), 
           False if col[0] == '-' else True) 
           for col in sort_cols]) 
    kwargs.update(dict(columns=list(columns), ascending=ascending)) 
    return kwargs 
+2

Questo sembra eccessivo, rispetto ad altre opzioni. – digitaldavenyc

+0

guarda solo all'esempio, non alla funzione 'sortkwargs'. questa è una definizione unica che puoi archiviare e importare dal tuo es. 'Util.py'. il tuo codice sarà molto più flessibile e leggibile rispetto alla sintassi di default 'sort'. – miraculixx

+0

voto giù tutto quello che ti piace, si prega di aggiungere un commento in modo da poter migliorare la risposta – miraculixx

7

Il metodo dataframe.sort() è, quindi, la mia comprensione - deprecato in panda> 0.18. Al fine di risolvere il problema è necessario utilizzare dataframe.sort_values ​​() invece:

f.sort_values(by=["c1","c2"], ascending=[False, True]) 

L'output è simile al seguente:

c1 c2 
    3 10 
    2 15 
    2 30 
    2 100 
    1 20 
4

Nel mio caso, la risposta accettata non ha funzionato:

f.sort_values ​​(di = [ "C1", "C2"], ascendente = [false, true])

quanto segue lavorato solo come previsto:

f = f.sort_values(by=["c1","c2"], ascending=[False, True]) 
+2

Seriamente? C'è qualcosa chiamato [inplace] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort.html) in Panda che conosci – Hng

Problemi correlati