Liste aus Pandas DataFrame-Spaltenüberschriften abrufen

1015

Ich möchte eine Liste der Spaltenüberschriften von einem Pandas DataFrame erhalten. Der DataFrame wird von Benutzereingaben stammen, sodass ich nicht weiß, wie viele Spalten vorhanden sein werden oder wie sie aufgerufen werden.

Zum Beispiel, wenn ich einen DataFrame wie diesen bekomme:

>>> my_dataframe
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7

Ich würde gerne eine Liste wie diese bekommen:

>>> header_list
['y', 'gdp', 'cap']
natsuki_2002
quelle

Antworten:

1646

Sie können die Werte als Liste abrufen, indem Sie Folgendes tun:

list(my_dataframe.columns.values)

Sie können auch einfach Folgendes verwenden: (wie in Ed Chums Antwort gezeigt ):

list(my_dataframe)
Simeon Visser
quelle
42
Warum hat dieses Dokument kein columnsAttribut?
Tjorriemorrie
@Tjorriemorrie: Ich bin mir nicht sicher, ob es damit zu tun hat, wie sie ihre Dokumentation automatisch generieren. Es wird jedoch an anderen Stellen erwähnt: pandas.pydata.org/pandas-docs/stable/…
Simeon Visser
8
Ich hätte so etwas erwartet df.column_names(). Ist diese Antwort immer noch richtig oder veraltet?
Alvas
1
@alvas Es gibt verschiedene andere Möglichkeiten, dies zu tun (siehe andere Antworten auf dieser Seite), aber meines Wissens gibt es keine Methode im Datenrahmen, um die Liste direkt zu erstellen.
Simeon Visser
19
Wichtig ist, dass die Spaltenreihenfolge erhalten bleibt.
WindChimes
402

Es gibt eine eingebaute Methode, die am leistungsfähigsten ist:

my_dataframe.columns.values.tolist()

.columnsGibt einen Index zurück, .columns.valuesgibt ein Array zurück und verfügt über eine Hilfsfunktion .tolistzum Zurückgeben einer Liste.

Wenn Ihnen die Leistung nicht so wichtig ist, Indexdefinieren Objekte eine .tolist()Methode, die Sie direkt aufrufen können:

my_dataframe.columns.tolist()

Der Leistungsunterschied ist offensichtlich:

%timeit df.columns.tolist()
16.7 µs ± 317 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit df.columns.values.tolist()
1.24 µs ± 12.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Für diejenigen , die Typisierung hassen, können Sie einfach anrufen listauf df, wie so:

list(df)
EdChum
quelle
4
Ich habe nicht abgestimmt, möchte aber erklären: Verlassen Sie sich nicht auf Implementierungsdetails, verwenden Sie die "öffentliche Schnittstelle" von DataFrame. Denken Sie an die Schönheit von df.keys ()
Sascha Gottfried
3
@SaschaGottfried Die Implementierung der DataFrameIterable hat sich seit dem ersten Tag nicht geändert: pandas.pydata.org/pandas-docs/stable/basics.html#iteration . Das von einem DataFrame zurückgegebene iterable war immer die Spalte, daher for col in df:sollte sich das immer gleich verhalten, es sei denn, die Entwickler haben eine Kernschmelze, so list(df)ist dies und sollte immer noch eine gültige Methode sein. Beachten Sie, dass df.keys()die interne Implementierung der diktartigen Struktur aufgerufen wird, wobei die Schlüssel zurückgegeben werden, die die Spalten sind. Unerklärliche Abstimmungen sind der Kollateralschaden, der auf SO zu erwarten ist. Machen Sie sich also keine Sorgen
EdChum
Ich bezog mich auf die Implementierungsdetails des columnsAttributs. Vor einer Stunde habe ich über das Gesetz von Demeter gelesen, das besagt, dass der Anrufer nicht von der Navigation im internen Objektmodell abhängen sollte. list(df)führt eine explizite Typkonvertierung durch. Bemerkenswerter Nebeneffekt: Die Erhöhung der Ausführungszeit und des Speicherverbrauchs mit der Datenrahmengrößenmethode df.keys()ist Teil der diktierten Natur von a DataFrame. Bemerkenswerte Tatsache: Die Ausführungszeit für df.keys()ist unabhängig von der Größe des Datenrahmens ziemlich konstant - Teil der Verantwortung der Pandas-Entwickler.
Sascha Gottfried
1
@SaschaGottfried Ich kann dies zu meiner Antwort hinzufügen und Ihnen
gutschreiben
1
Ich kann Wert sowohl in der gegebenen Antwort als auch in den Kommentaren sehen - nichts muss geändert werden.
Sascha Gottfried
89

Habe einige schnelle Tests durchgeführt, und es ist vielleicht nicht überraschend, dass die integrierte Version dataframe.columns.values.tolist()die schnellste ist:

In [1]: %timeit [column for column in df]
1000 loops, best of 3: 81.6 µs per loop

In [2]: %timeit df.columns.values.tolist()
10000 loops, best of 3: 16.1 µs per loop

In [3]: %timeit list(df)
10000 loops, best of 3: 44.9 µs per loop

In [4]: % timeit list(df.columns.values)
10000 loops, best of 3: 38.4 µs per loop

(Ich mag das immer noch sehr list(dataframe), also danke EdChum!)

Tegan
quelle
47

Es wird noch einfacher (von Pandas 0.16.0):

df.columns.tolist()

gibt Ihnen die Spaltennamen in einer schönen Liste.

fixxxer
quelle
37
>>> list(my_dataframe)
['y', 'gdp', 'cap']

Verwenden Sie ein Listenverständnis, um die Spalten eines Datenrahmens im Debugger-Modus aufzulisten:

>>> [c for c in my_dataframe]
['y', 'gdp', 'cap']

Übrigens können Sie eine sortierte Liste erhalten, indem Sie einfach Folgendes verwenden sorted:

>>> sorted(my_dataframe)
['cap', 'gdp', 'y']
Alexander
quelle
Würde das list(df)nur mit Autoincrement-Datenrahmen funktionieren? Oder funktioniert es für alle Datenrahmen?
Alvas
2
Sollte für alle funktionieren. Wenn Sie sich im Debugger befinden, müssen Sie jedoch ein Listenverständnis verwenden [c for c in df].
Alexander
25

Überrascht habe ich das bisher noch nicht gesehen, also lasse ich es einfach hier.

Erweitertes iterierbares Entpacken (python3.5 +): [*df] und Freunde

Das Entpacken von Verallgemeinerungen (PEP 448) wurde mit Python 3.5 eingeführt. Die folgenden Operationen sind also alle möglich.

df = pd.DataFrame('x', columns=['A', 'B', 'C'], index=range(5))
df

   A  B  C
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x 

Wenn Sie eine list....

[*df]
# ['A', 'B', 'C']

Oder, wenn Sie eine wollen set,

{*df}
# {'A', 'B', 'C'}

Oder, wenn Sie eine wollen tuple,

*df,  # Please note the trailing comma
# ('A', 'B', 'C')

Oder wenn Sie das Ergebnis irgendwo speichern möchten,

*cols, = df  # A wild comma appears, again
cols
# ['A', 'B', 'C']

... wenn Sie die Art von Person sind, die Kaffee in Tippgeräusche umwandelt, wird dies Ihren Kaffee effizienter konsumieren;)

PS: Wenn Leistung wichtig ist, sollten Sie die oben genannten Lösungen zugunsten von ablehnen

df.columns.to_numpy().tolist()
# ['A', 'B', 'C']

Dies ähnelt der Antwort von Ed Chum , wurde jedoch für Version 0.24 aktualisiert, wobei .to_numpy()die Verwendung von bevorzugt wird .values. Weitere Informationen finden Sie in dieser Antwort (von mir).

Visuelle Überprüfung
Da ich dies in anderen Antworten gesehen habe, können Sie iterierbares Entpacken verwenden (keine expliziten Schleifen erforderlich).

print(*df)
A B C

print(*df, sep='\n')
A
B
C

Kritik anderer Methoden

Verwenden Sie keine explizite forSchleife für eine Operation, die in einer einzelnen Zeile ausgeführt werden kann (Listenverständnisse sind in Ordnung).

Bei Verwendung von sorted(df) wird die ursprüngliche Reihenfolge der Spalten nicht beibehalten . Dafür sollten Sie list(df)stattdessen verwenden.

Weiter list(df.columns)und list(df.columns.values)sind schlechte Vorschläge (ab der aktuellen Version, v0.24). Sowohl Index(zurückgegeben von df.columns) als auch NumPy-Arrays (zurückgegeben von df.columns.values) definieren eine .tolist()Methode, die schneller und idiomatischer ist.

Schließlich sollte die Auflistung, dh, list(df)nur als prägnante Alternative zu den oben genannten Methoden für Python <= 3.4 verwendet werden, bei denen kein erweitertes Entpacken verfügbar ist.

cs95
quelle
24

Das ist verfügbar als my_dataframe.columns.

BrenBarn
quelle
1
Und explizit als Liste vonheader_list = list(my_dataframe.columns)
Yeliabsalohcin
^ Oder noch besser : df.columns.tolist().
CS95
18

Es ist interessant, aber df.columns.values.tolist()dann fast dreimal schneller, df.columns.tolist()aber ich dachte, dass sie gleich sind:

In [97]: %timeit df.columns.values.tolist()
100000 loops, best of 3: 2.97 µs per loop

In [98]: %timeit df.columns.tolist()
10000 loops, best of 3: 9.67 µs per loop
Anton Protopopov
quelle
2
Das Timing wurde in dieser Antwort bereits behandelt . Der Grund für die Diskrepanz liegt darin, dass .valuesdas zugrunde liegende Numpy-Array zurückgegeben wird und es fast immer schneller ist, etwas mit Numpy zu tun, als dasselbe mit Pandas direkt zu tun.
CS95
17

Ein DataFrame folgt der diktartigen Konvention, über die „Schlüssel“ der Objekte zu iterieren.

my_dataframe.keys()

Erstellen Sie eine Liste von Schlüsseln / Spalten - Objektmethode to_list()und pythonische Methode

my_dataframe.keys().to_list()
list(my_dataframe.keys())

Die grundlegende Iteration in einem DataFrame gibt Spaltenbeschriftungen zurück

[column for column in my_dataframe]

Konvertieren Sie einen DataFrame nicht in eine Liste, nur um die Spaltenbeschriftungen zu erhalten. Hören Sie nicht auf zu denken, während Sie nach praktischen Codebeispielen suchen.

xlarge = pd.DataFrame(np.arange(100000000).reshape(10000,10000))
list(xlarge) #compute time and memory consumption depend on dataframe size - O(N)
list(xlarge.keys()) #constant time operation - O(1)
Sascha Gottfried
quelle
2
Meine Tests zeigen, dass df.columnses viel schneller ist als df.keys(). Ich bin mir nicht sicher, warum sie sowohl eine Funktion als auch ein Attribut für dasselbe haben (nun, es ist nicht das erste Mal, dass ich 10 verschiedene Möglichkeiten gesehen habe, etwas in Pandas zu tun).
CS95
1
Die Absicht meiner Antwort war es, einige Möglichkeiten aufzuzeigen, um Spaltenbeschriftungen von einem DataFrame abzufragen und ein Leistungs-Anti-Pattern hervorzuheben. Trotzdem mag ich Ihre Kommentare und habe Ihre jüngste Antwort positiv bewertet - da sie aus Sicht der Softwareentwicklung einen Mehrwert bieten.
Sascha Gottfried
14

Im Notizbuch

Für die Datenexploration im IPython-Notizbuch bevorzuge ich Folgendes:

sorted(df)

Dadurch wird eine einfach zu lesende alphabetisch geordnete Liste erstellt.

In einem Code-Repository

Im Code finde ich es expliziter zu tun

df.columns

Weil es anderen, die Ihren Code lesen, sagt, was Sie tun.

Firelynx
quelle
sorted(df)ändert die Reihenfolge. Mit Vorsicht verwenden.
CS95
@coldspeed Ich erwähne dies jedoch, "was eine einfach zu lesende alphabetisch geordnete Liste ergibt."
Firelynx
9
%%timeit
final_df.columns.values.tolist()
948 ns ± 19.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%%timeit
list(final_df.columns)
14.2 µs ± 79.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
list(final_df.columns.values)
1.88 µs ± 11.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%%timeit
final_df.columns.tolist()
12.3 µs ± 27.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
list(final_df.head(1).columns)
163 µs ± 20.6 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Rohit Singh
quelle
3

wie von Simeon Visser beantwortet ... könnten Sie tun

list(my_dataframe.columns.values) 

oder

list(my_dataframe) # for less typing.

Aber ich denke am meisten ist der Sweet Spot:

list(my_dataframe.columns)

Es ist explizit, gleichzeitig nicht unnötig lang.

Vivek
quelle
"Es ist explizit, gleichzeitig nicht unnötig lang." Ich stimme dir nicht zu. Das listAnrufen hat keinen Wert, es sei denn, Sie rufen es dfdirekt an (z. B. Prägnanz). Der Zugriff auf das .columnsAttribut gibt ein IndexObjekt zurück, für das eine tolist()Methode definiert ist, und der Aufruf ist idiomatischer als das Auflisten des Index. Das Mischen von Redewendungen nur der Vollständigkeit halber ist keine gute Idee. Gleiches gilt für die Auflistung des Arrays, von dem Sie erhalten .values.
CS95
3

Versuchen Sie Folgendes, um eine schnelle, saubere und visuelle Überprüfung zu erhalten:

for col in df.columns:
    print col
Joseph True
quelle
3

Dies gibt uns die Namen der Spalten in einer Liste:

list(my_dataframe.columns)

Eine andere Funktion namens tolist () kann ebenfalls verwendet werden:

my_dataframe.columns.tolist()
Harikrishna
quelle
Dies wurde bereits in anderen Antworten behandelt. Ihre erste Lösung mischt auch Redewendungen, was keine gute Idee ist. Siehe meinen Kommentar unter einer anderen Antwort.
CS95
2

Ich bin der Meinung, dass die Frage eine zusätzliche Erklärung verdient.

Wie @fixxxer feststellte, hängt die Antwort von der Pandas-Version ab, die Sie in Ihrem Projekt verwenden. Was Sie mit pd.__version__Befehl bekommen können .

Wenn Sie aus irgendeinem Grund wie ich (auf Debian Jessie verwende ich 0.14.1) eine ältere Version von Pandas als 0.16.0 verwenden, müssen Sie Folgendes verwenden:

df.keys().tolist()weil noch keine df.columnsMethode implementiert ist.

Der Vorteil dieser Schlüsselmethode ist, dass sie auch in neueren Versionen von Pandas funktioniert und somit universeller ist.

StefanK
quelle
Der Nachteil von keys () ist, dass es sich eher um einen Funktionsaufruf als um eine Attributsuche handelt, sodass es immer langsamer wird. Natürlich kümmert sich bei konstanten Zeitzugriffen niemand wirklich um solche Unterschiede, aber ich denke, es ist trotzdem erwähnenswert; df.columns ist jetzt eine allgemein akzeptierte Redewendung für den Zugriff auf Header.
cs95
1
n = []
for i in my_dataframe.columns:
    n.append(i)
print n
user21988
quelle
6
Bitte ersetzen Sie es durch ein Listenverständnis.
Sascha Gottfried
4
Ändern Sie Ihre ersten 3 Zeilen in[n for n in dataframe.columns]
Anton Protopopov
Warum sollten Sie all diese Probleme für eine Operation durchgehen wollen, die Sie problemlos in einer einzigen Zeile ausführen können?
CS95
0

Auch wenn die oben angegebene Lösung nett ist. Ich würde auch erwarten, dass etwas wie frame.column_names () eine Funktion in Pandas ist, aber da dies nicht der Fall ist, wäre es vielleicht schön, die folgende Syntax zu verwenden. Es bewahrt irgendwie das Gefühl, dass Sie Pandas richtig verwenden, indem Sie die Funktion "tolist" aufrufen: frame.columns.tolist ()

frame.columns.tolist() 
Igor Jakovljevic
quelle
0

Wenn der DataFrame zufällig einen Index oder MultiIndex hat und Sie möchten, dass diese auch als Spaltennamen enthalten sind:

names = list(filter(None, df.index.names + df.columns.values.tolist()))

Es wird vermieden, reset_index () aufzurufen, was für eine so einfache Operation einen unnötigen Leistungseinbruch zur Folge hat.

Ich brauche dies häufiger, weil ich Daten aus Datenbanken pendle, in denen der Datenrahmenindex einem Primär- / eindeutigen Schlüssel zugeordnet ist, aber für mich eigentlich nur eine weitere "Spalte" ist. Für Pandas wäre es wahrscheinlich sinnvoll, eine eingebaute Methode für so etwas zu haben (möglicherweise habe ich sie verpasst).

totalhack
quelle
-1

Diese Lösung listet alle Spalten Ihres Objekts my_dataframe auf:

print(list(my_dataframe))
Sunitha G.
quelle