Ottieni l'elenco dalle intestazioni di colonna Panda DataFrame


1017

Voglio ottenere un elenco delle intestazioni di colonna da un DataFrame Panda. DataFrame verrà dall'input dell'utente, quindi non saprò quante colonne ci saranno o come verranno chiamate.

Ad esempio, se mi viene dato un DataFrame come questo:

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

Vorrei ottenere un elenco come questo:

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

Risposte:


1648

È possibile ottenere i valori come elenco facendo:

list(my_dataframe.columns.values)

Inoltre puoi semplicemente usare: (come mostrato nella risposta di Ed Chum ):

list(my_dataframe)

42
Perché questo documento non ha columnscome attributo?
Tjorriemorrie,

@Tjorriemorrie: Non sono sicuro, potrebbe avere a che fare con il modo in cui generano automaticamente la loro documentazione. È menzionato in altri luoghi: pandas.pydata.org/pandas-docs/stable/…
Simeon Visser

8
Mi sarei aspettato qualcosa del genere df.column_names(). Questa risposta è ancora corretta o è obsoleta?
alvas

1
@alvas ci sono molti altri modi per farlo (vedi altre risposte in questa pagina) ma per quanto ne so non c'è un metodo sul frame di dati direttamente per produrre la lista.
Simeon Visser,

19
È importante sottolineare che ciò preserva l'ordine delle colonne.
WindChimes,

404

Esiste un metodo integrato che è il più performante:

my_dataframe.columns.values.tolist()

.columnsrestituisce un indice, .columns.valuesrestituisce un array e questo ha una funzione di supporto.tolist per restituire un elenco.

Se le prestazioni non sono così importanti per te, gli Indexoggetti definiscono un .tolist()metodo che puoi chiamare direttamente:

my_dataframe.columns.tolist()

La differenza nelle prestazioni è evidente:

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

Per coloro che odiano la digitazione, si può chiamare listil df, come così:

list(df)

4
Non ho votato al ribasso, ma voglio spiegare: non fare affidamento sui dettagli di implementazione, utilizzare "interfaccia pubblica" di DataFrame. Pensa alla bellezza di df.keys ()
Sascha Gottfried

3
@SaschaGottfried l'implementazione DataFramedell'iterabile non è cambiata dal primo giorno: pandas.pydata.org/pandas-docs/stable/basics.html#iteration . L'iterabile restituito da un DataFrame è sempre stato le colonne, quindi fare for col in df:dovrebbe sempre comportarsi allo stesso modo a meno che gli sviluppatori non abbiano un crollo così list(df)sia e dovrebbe essere comunque un metodo valido. Si noti che df.keys()sta chiamando l'implementazione interna della struttura simil-dict che restituisce le chiavi che sono le colonne. Downvotes inspiegabili è il danno collaterale che ci si aspetta da SO quindi non preoccuparti
EdChum

Mi riferivo ai dettagli di implementazione columnsdell'attributo. Un'ora fa ho letto della Legge di Demetra promuovendo che il chiamante non dovrebbe dipendere dalla navigazione del modello di oggetti interno. list(df)esegue una conversione esplicita del tipo. Notevole effetto collaterale: il tempo di esecuzione e il consumo di memoria aumentano con il df.keys()metodo delle dimensioni del frame di dati fa parte della natura simile a un a DataFrame. Fatto notevole: il tempo di esecuzione df.keys()è piuttosto costante, indipendentemente dalle dimensioni del frame di dati, parte della responsabilità degli sviluppatori di Panda.
Sascha Gottfried,

1
@SaschaGottfried Posso aggiungere questo alla mia risposta e darle credito visto che nessun altro lo ha incluso
EdChum

1
Riesco a vedere il valore sia nella risposta data che nei commenti: non è necessario modificare nulla.
Sascha Gottfried,

89

Ha fatto alcuni test rapidi e forse non sorprende che la versione integrata che utilizza dataframe.columns.values.tolist()sia la più veloce:

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

(Mi piace ancora molto il list(dataframe)pensiero, quindi grazie EdChum!)


47

Diventa ancora più semplice (di Panda 0.16.0):

df.columns.tolist()

ti darà i nomi delle colonne in una bella lista.


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

Per elencare le colonne di un frame di dati mentre si è in modalità debugger, utilizzare una comprensione dell'elenco:

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

A proposito, puoi ottenere un elenco ordinato semplicemente usando sorted:

>>> sorted(my_dataframe)
['cap', 'gdp', 'y']

Vorrei che list(df)il lavoro solo con i dataframes autoincremento? O funziona per tutti i frame di dati?
alvas

2
Dovrebbe funzionare per tutti. Quando si è nel debugger, tuttavia, è necessario utilizzare una comprensione dell'elenco [c for c in df].
Alexander

25

Sorpreso non ho visto questo post finora, quindi lo lascerò qui.

Extended Iterable Unpacking (python3.5 +): [*df]and Friends

Le generalizzazioni di decompressione (PEP 448) sono state introdotte con Python 3.5. Quindi, le seguenti operazioni sono tutte possibili.

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 

Se vuoi un list....

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

Oppure, se vuoi un set,

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

Oppure, se vuoi un tuple,

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

Oppure, se si desidera memorizzare il risultato da qualche parte,

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

... se sei il tipo di persona che converte il caffè in suoni di battitura, beh, questo consumerà il tuo caffè in modo più efficiente;)

PS: se le prestazioni sono importanti, vorrai abbandonare le soluzioni sopra a favore di

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

Questo è simile alla risposta di Ed Chum , ma aggiornato per v0.24 dove .to_numpy()è preferito l'uso di .values. Vedi questa risposta (da me) per maggiori informazioni.

Controllo visivo
Poiché ne ho visto la discussione in altre risposte, è possibile utilizzare la decompressione iterabile (non sono necessari loop espliciti).

print(*df)
A B C

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

Critica ad altri metodi

Non usare un esplicito for ciclo per un'operazione che può essere eseguita su una sola riga (le comprensioni dell'elenco sono corrette).

Successivamente, l'utilizzo sorted(df) non mantiene l'ordine originale delle colonne. Per questo, dovresti usarelist(df) invece.

Quindi, list(df.columns)e list(df.columns.values)suggerimenti scadenti (a partire dalla versione corrente, v0.24). Entrambi Index(tornati da df.columns) e array NumPy (restituiti da df.columns.values) definiscono.tolist() metodo che è più veloce e più idiomatica.

Infine, l'elenco, ad esempio, list(df)dovrebbe essere usato solo come alternativa concisa ai metodi di cui sopra per python <= 3.4 dove non è disponibile il decompressione estesa.


24

È disponibile come my_dataframe.columns.


1
Ed esplicitamente come un elenco diheader_list = list(my_dataframe.columns)
yeliabsalohcin,

^ O meglio ancora: df.columns.tolist().
cs95,

18

È interessante ma df.columns.values.tolist()è quasi 3 volte più veloce di allora, df.columns.tolist()ma ho pensato che fossero uguali:

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

2
I tempi sono già stati trattati in questa risposta . Il motivo della discrepanza è perché .valuesrestituisce l'array numpy sottostante e fare qualcosa con numpy è quasi sempre più veloce che fare la stessa cosa direttamente con i panda.
cs95,

17

Un DataFrame segue la convenzione tipo dict di iterare sulle "chiavi" degli oggetti.

my_dataframe.keys()

Crea un elenco di chiavi / colonne - metodo oggetto to_list()e modo pitonico

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

L'iterazione di base su un DataFrame restituisce le etichette delle colonne

[column for column in my_dataframe]

Non convertire un DataFrame in un elenco, solo per ottenere le etichette delle colonne. Non smettere di pensare mentre cerchi esempi di codice convenienti.

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)

2
I miei test mostrano che df.columnsè molto più veloce di df.keys(). Non sono sicuro del perché abbiano sia una funzione che un attributo per la stessa cosa (beh, non è la prima volta che vedo 10 modi diversi di fare qualcosa nei panda).
cs95,

1
L'intenzione della mia risposta era di mostrare un paio di modi per interrogare le etichette delle colonne da un DataFrame ed evidenziare un modello anti-prestazioni. Tuttavia, mi piacciono i tuoi commenti e ho votato a fondo la tua risposta recente, poiché forniscono valore dal punto di vista dell'ingegneria del software.
Sascha Gottfried,

14

Nel quaderno

Per l'esplorazione dei dati nel notebook IPython, il mio modo preferito è questo:

sorted(df)

Che produrrà un elenco in ordine alfabetico facile da leggere.

In un repository di codice

Nel codice lo trovo più esplicito da fare

df.columns

Perché dice agli altri che leggono il tuo codice cosa stai facendo.


sorted(df)cambia l'ordine. Usare con cautela.
cs95,

@coldspeed Cito questo anche se "Che produrrà un elenco in ordine alfabetico di facile lettura".
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)

3

come ha risposto Simeon Visser ... potresti farlo

list(my_dataframe.columns.values) 

o

list(my_dataframe) # for less typing.

Ma penso che la cosa migliore sia:

list(my_dataframe.columns)

È esplicito, allo stesso tempo non inutilmente lungo.


"È esplicito, allo stesso tempo non inutilmente lungo." Non sono d'accordo. La chiamata listnon ha alcun merito se non la si chiama dfdirettamente (ad esempio, concisione). L'accesso .columnsall'attributo restituisce un Indexoggetto su cui è tolist()definito un metodo e una chiamata più idiomatica dell'elenco Index. Mischiare idiomi solo per completezza non è una grande idea. Lo stesso vale per l'elenco dell'array da cui si ottiene .values.
cs95,

3

Per un controllo visivo rapido e accurato, prova questo:

for col in df.columns:
    print col

3

Questo ci dà i nomi delle colonne in un elenco:

list(my_dataframe.columns)

È possibile utilizzare anche un'altra funzione chiamata tolist ():

my_dataframe.columns.tolist()

Questo è già stato trattato in altre risposte. La tua prima soluzione mescola anche modi di dire, il che non è una grande idea. Vedi il mio commento sotto un'altra risposta.
cs95,

2

Sento che la domanda merita ulteriori spiegazioni.

Come notato da @fixxxer, la risposta dipende dalla versione di Panda che stai usando nel tuo progetto. Che puoi ottenere con il pd.__version__comando.

Se sei per qualche ragione come me (su Debian Jessie uso 0.14.1) usando una versione precedente di Panda rispetto a 0.16.0, allora devi usare:

df.keys().tolist()perché non esiste ancora un df.columnsmetodo implementato.

Il vantaggio di questo metodo di chiavi è che funziona anche nella versione più recente di Panda, quindi è più universale.


Il contro di chiavi () è che è una chiamata di funzione piuttosto che una ricerca di attributi, quindi sarà sempre più lenta. Certo, con accessi a tempo costante, a nessuno importa davvero delle differenze come queste, ma penso che valga la pena menzionarle comunque; df.columns è ora un linguaggio più universalmente accettato per l'accesso alle intestazioni.
cs95,

1
n = []
for i in my_dataframe.columns:
    n.append(i)
print n

6
si prega di sostituirlo con una comprensione dell'elenco.
Sascha Gottfried,

4
cambia le tue prime 3 righe in[n for n in dataframe.columns]
Anton Protopopov il

Perché dovresti voler affrontare tutti questi problemi per un'operazione che puoi facilmente fare in una sola riga?
cs95,

0

Anche se la soluzione fornita sopra è buona. Mi aspetterei anche che qualcosa come frame.column_names () sia una funzione in Panda, ma poiché non lo è, forse sarebbe bello usare la seguente sintassi. In qualche modo conserva la sensazione che stai usando i panda in modo corretto chiamando la funzione "tolist": frame.columns.tolist ()

frame.columns.tolist() 

0

Se il DataFrame sembra avere un indice o MultiIndex e si desidera includere anche quelli come nomi di colonna:

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

Evita di chiamare reset_index () che ha un impatto sulle prestazioni non necessario per un'operazione così semplice.

Ho avuto bisogno di questo più spesso perché sto spostando i dati dai database in cui l'indice del frame di dati viene mappato su una chiave primaria / unica, ma in realtà è solo un'altra "colonna" per me. Probabilmente avrebbe senso per i panda avere un metodo integrato per qualcosa del genere (totalmente possibile che mi sia perso).


-1

Questa soluzione elenca tutte le colonne dell'oggetto my_dataframe:

print(list(my_dataframe))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.