475 Stimmen

Wie kann man ein DataFrame in Python-Pandas nach zwei oder mehr Spalten sortieren?

Angenommen, ich habe ein DataFrame mit den Spalten a, b und c. Ich möchte das DataFrame nach der Spalte b in aufsteigender Reihenfolge und nach der Spalte c in absteigender Reihenfolge sortieren. Wie mache ich das?

836voto

Andy Hayden Punkte 324102

Ab dem Release 0.17.0 wurde die sort Methode zugunsten von sort_values veraltet. sort wurde im Release 0.20.0 komplett entfernt. Die Argumente (und Ergebnisse) bleiben gleich:

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

Sie können das ascending Argument von sort verwenden:

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

Zum Beispiel:

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

Sort ist standardmäßig nicht inplace! Daher sollten Sie das Ergebnis der Sortiermethode einer Variablen zuweisen oder inplace=True zum Methodenaufruf hinzufügen.

d.h., 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)

81voto

Kyle Heuton Punkte 9188

Ab pandas 0.17.0 ist DataFrame.sort() veraltet und wird in einer zukünftigen Version von pandas entfernt werden. Der Weg, ein DataFrame nach seinen Werten zu sortieren, ist jetzt DataFrame.sort_values

Als solches wäre die Antwort auf Ihre Frage jetzt

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

16voto

jpp Punkte 146159

Für große Dataframes mit numerischen Daten kann eine signifikante Leistungssteigerung durch numpy.lexsort erzielt werden, das eine indirekte Sortierung mithilfe einer Sequenz von Schlüsseln durchführt:

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 pro Schleife
%timeit lex(df1)     # 143 ms pro Schleife

Eine Besonderheit ist, dass die definierte Sortierreihenfolge mit numpy.lexsort umgekehrt ist: (-'b', 'a') sortiert zuerst nach der Serie a. Wir negieren die Serie b, um anzuzeigen, dass wir diese Serie absteigend möchten.

Beachten Sie, dass np.lexsort nur mit numerischen Werten sortiert, während pd.DataFrame.sort_values sowohl mit Zeichenfolgen als auch mit numerischen Werten funktioniert. Die Verwendung von np.lexsort mit Zeichenfolgen führt zu: TypeError: bad operand type for unary -: 'str'.

0voto

Für diejenigen, die hier für ein mehrspaltiges DataFrame kommen, verwenden Sie Tupel mit Elementen, die jedem Level entsprechen.

Tupel mit Elementen, die jedem Level entsprechen:

d = {}
d['first_level'] = pd.DataFrame(columns=['idx', 'a', 'b', 'c'],
                                         data=[[10, 0.89, 0.98, 0.31],
                                               [20, 0.34, 0.78, 0.34]]).set_index('idx')
d['second_level'] = pd.DataFrame(columns=['idx', 'a', 'b', 'c'],
                                          data=[[10, 0.29, 0.63, 0.99],
                                                [20, 0.23, 0.26, 0.98]]).set_index('idx')

df = pd.concat(d, axis=1)
df.sort_values(('second_level', 'b'))

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X