Wie sortiere ich einen Datenrahmen in Python-Pandas nach zwei oder mehr Spalten?

Antworten:

454

Ab der Version 0.17.0 wurde die sortMethode zugunsten von abgelehnt sort_values. sortwurde in der Version 0.20.0 vollständig entfernt. Die Argumente (und Ergebnisse) bleiben gleich:

df.sort_values(['a', 'b'], ascending=[True, False])

Sie können das aufsteigende Argument verwenden von sort:

df.sort(['a', 'b'], ascending=[True, False])

Beispielsweise:

In [11]: df1 = pd.DataFrame(np.random.randint(1, 5, (10,2)), columns=['a','b'])

In [12]: df1.sort(['a', 'b'], ascending=[True, False])
Out[12]:
   a  b
2  1  4
7  1  3
1  1  2
3  1  2
4  3  2
6  4  4
0  4  3
9  4  3
5  4  1
8  4  1

Wie von @renadeen kommentiert

Die Sortierung ist standardmäßig nicht vorhanden! Sie sollten also das Ergebnis der Sortiermethode einer Variablen zuweisen oder dem Methodenaufruf inplace = True hinzufügen.

Das heißt, wenn Sie df1 als sortierten DataFrame wiederverwenden möchten:

df1 = df1.sort(['a', 'b'], ascending=[True, False])

oder

df1.sort(['a', 'b'], ascending=[True, False], inplace=True)
Andy Hayden
quelle
6
Die Sortierung ist standardmäßig nicht vorhanden! Sie sollten also das Ergebnis der sortMethode einer Variablen zuweisen oder inplace=Truedem Methodenaufruf hinzufügen .
Renadeen
2
@renadeen sehr guter Punkt, ich habe durch Antwort mit diesem Kommentar aktualisiert.
Andy Hayden
1
Ich war überrascht zu erfahren, dass diese Sorte heute veraltet ist! Basierend auf einigen Meinungen in diesem Meta-Beitrag: meta.stackoverflow.com/questions/297404/… Ich habe beschlossen, eine neue Antwort hinzuzufügen, anstatt zu versuchen, Ihre zu bearbeiten
Kyle Heuton
2
@Snoozer Ja, ich glaube nicht, dass die Sortierung jemals verschwinden wird (hauptsächlich, da sie in Wes 'Buch ausgiebig verwendet wird), aber es gab einige große Änderungen beim Aufrufen der Sortierung . Vielen Dank! .. Ich muss wirklich automatisieren, alle meine 1000 Pandas Antworten auf Verwerfungen durchzugehen!
Andy Hayden
40

Ab Pandas 0.17.0 DataFrame.sort()ist es veraltet und wird in einer zukünftigen Version von Pandas entfernt. Die Möglichkeit, einen Datenrahmen nach seinen Werten zu sortieren, ist jetztDataFrame.sort_values

Als solche wäre die Antwort auf Ihre Frage jetzt

df.sort_values(['b', 'c'], ascending=[True, False], inplace=True)
Kyle Heuton
quelle
4

Bei großen Datenrahmen mit numerischen Daten kann es zu einer signifikanten Leistungsverbesserung kommen numpy.lexsort, bei der eine indirekte Sortierung mithilfe einer Tastenfolge durchgeführt wird:

import pandas as pd
import numpy as np

np.random.seed(0)

df1 = pd.DataFrame(np.random.randint(1, 5, (10,2)), columns=['a','b'])
df1 = pd.concat([df1]*100000)

def pdsort(df1):
    return df1.sort_values(['a', 'b'], ascending=[True, False])

def lex(df1):
    arr = df1.values
    return pd.DataFrame(arr[np.lexsort((-arr[:, 1], arr[:, 0]))])

assert (pdsort(df1).values == lex(df1).values).all()

%timeit pdsort(df1)  # 193 ms per loop
%timeit lex(df1)     # 143 ms per loop

Eine Besonderheit ist, dass die definierte Sortierreihenfolge mit numpy.lexsortumgekehrt ist: zuerst (-'b', 'a')nach Serien sortieren a. Wir negieren Serien b, um zu reflektieren, dass wir diese Serien in absteigender Reihenfolge haben möchten.

Beachten Sie, dass np.lexsortnur mit numerischen Werten sortiert wird, während pd.DataFrame.sort_valuesentweder mit Zeichenfolgen oder mit numerischen Werten gearbeitet wird. Die Verwendung np.lexsortmit Zeichenfolgen ergibt : TypeError: bad operand type for unary -: 'str'.

jpp
quelle