2013-07-12 21 views
44

Ich habe folgenden Datenrahmen:Wie Pandas Datenrahmen mit Werten aus mehreren Spalten zu sortieren?

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

Oder in für Menschen lesbare Form:

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

Folgende Sortier-Befehl arbeitet wie erwartet:

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

Output:

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

Aber der folgenden Befehl ein:

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

Ergebnisse in

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

und das ist nicht das, was ich erwarte. Ich erwarte, dass die Werte in der ersten Spalte vom größten zum kleinsten sortiert sind, und wenn in der ersten Spalte identische Werte vorhanden sind, sortiere nach den aufsteigenden Werten aus der zweiten Spalte.

Weiß jemand, warum es nicht wie erwartet funktioniert?

ADDED

Dies ist copy-paste:

>>> 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

Welche Version von Pandas und numpy verwenden Sie? –

Antwort

42

Ihr Code funktioniert für mich.

>>> 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 

Haben fügen Sie wie?

>>> 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 ist veraltet; Verwenden Sie 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

Vorschlag: umgekehrte Reihenfolge mit Original unten, Update oben. Lesen von oben nach unten Ich versuchte den ersten Block und fragte mich, warum es scheiterte, doppelt verwirrt von "es funktioniert für mich" und "hast du Paste wie es ist" (sicherlich war es meine Schuld!). Dann gescrollt ich und sah das Update ... – Hendy

2

Wenn Sie diesen Code als Skriptdatei schreiben, dann werden Sie es so schreiben müssen:

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

Verwendung von sort in Warnmeldung führen kann. Siehe github Diskussion.

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

ich Warnung bin immer sonst '/Applications/anaconda/lib/python2.7/site-packages/spyderlib/widgets/externalshell/start_ipython_kernel.py:1: FutureWarning: sort (Spalten = ....) ist veraltet, verwenden Sie sort_values ​​(von = .....) ' – abhiieor

+0

@patapouf_ai Nein,' sort' jetzt veraltet ist – oulenz

1

ich gefunden habe, dies zu sein, wirklich nützlich: Sie könnten also die Verwendung sort_values, docs here

Dann wird Ihr Code wie folgt aussehen wollen

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'])) 

Beachten Sie, dass im Gegensatz zu den Standard columns=,ascending= Argumente, hier sind die Spaltennamen und ihre Sortierreihenfolge an der gleichen Stelle. Als Ergebnis wird Ihr Code viel einfacher zu lesen und zu pflegen.

Hinweis der tatsächliche Aufruf .sort unverändert ist, skw (s ort kw args) ist nur eine kleine Hilfsfunktion, die die Spalten und gibt die üblichen columns= und ascending= Parameter für Sie analysiert. Übergeben Sie es an jede andere Art von Kwarts, wie Sie es normalerweise tun würden. Kopieren Sie den folgenden Code, und fügen Sie ihn in z. Ihre lokale utils.py dann vergessen Sie es und verwenden Sie es einfach wie oben.

# 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

Dies scheint übertrieben, im Vergleich zu anderen Optionen. – digitaldavenyc

+0

Schauen Sie sich nur das Beispiel an, nicht die 'sortkwargs' Funktion. Das ist eine einmalige Definition, die Sie speichern und importieren können von Ihrem z. 'util.py'. Ihr Code wird im Vergleich zur Standard-Sortier-Syntax so viel flexibler und lesbarer sein. – miraculixx

+0

vote down alles, was Sie mögen, fügen Sie bitte einen Kommentar, damit ich die Antwort verbessern kann – miraculixx

7

Die Methode dataframe.sort() ist - so mein Verständnis - in Pandas> 0.18 veraltet. Um Ihr Problem zu lösen, sollten Sie dataframe.sort_values ​​verwenden() statt:

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

Der Ausgang dieses wie folgt aussieht:

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

In meinem Fall hat die akzeptierte Antwort nicht:

f.sort_values ​​(von = [ "c1", "c2"], aufsteigend = [false, True])

Nur die wie erwartet gearbeitet folgenden:

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

Ernsthaft? Es gibt etwas, das man [inplace] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort.html) in Pandas nennt – Hng

Verwandte Themen