Obtener la lista de los encabezados de columna de Pandas DataFrame

1177

Quiero obtener una lista de los encabezados de columna de un DataFrame de pandas. El DataFrame vendrá de la entrada del usuario, por lo que no sabré cuántas columnas habrá o cómo se llamarán.

Por ejemplo, si me dan un DataFrame como este:

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

Obtendría una lista como esta:

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

Puede obtener los valores como una lista haciendo:

list(my_dataframe.columns.values)

También puede simplemente usar: (como se muestra en la respuesta de Ed Chum ):

list(my_dataframe)
12
  • 46
    ¿Por qué este documento no tiene columnscomo atributo? Tjorriemorrie 21/11/2014 a las 8:30
  • 9
    Hubiera esperado algo como df.column_names(). ¿Esta respuesta sigue siendo correcta o está desactualizada? alvas 13 de enero de 2016 a las 6:48
  • 1
    @alvas, hay varias otras formas de hacerlo (vea otras respuestas en esta página) pero, hasta donde yo sé, no hay un método en el marco de datos directamente para producir la lista. Simeon Visser 13 de enero de 2016 a las 9:30
  • 21
    Es importante destacar que esto preserva el orden de las columnas. WindChimes 25 de enero de 2016 a las 13:07
  • 1
    Esta primera opción es terrible (a partir de la versión actual de pandas, v0.24) porque mezcla modismos . Si tiene problemas para acceder a la matriz numpy, utilice el .tolist()método en su lugar, es más rápido y más idiomático. cs95 3 abr 19 a las 9:50
462

Hay un método integrado que es el más eficaz:

my_dataframe.columns.values.tolist()

.columnsdevuelve un índice, .columns.valuesdevuelve una matriz y esto tiene una función auxiliar .tolistpara devolver una lista.

Si el rendimiento no es tan importante para usted, los Indexobjetos definen un .tolist()método al que puede llamar directamente:

my_dataframe.columns.tolist()

La diferencia de rendimiento es obvia:

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

Para los que odian a escribir, sólo puede llamar lista df, como así:

list(df)
101

Hice algunas pruebas rápidas y, tal vez, como era de esperar, la versión incorporada que usa dataframe.columns.values.tolist()es la más rápida:

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

(Aunque todavía me gusta mucho list(dataframe), ¡así que gracias EdChum!)

0
58

Se vuelve aún más simple (por pandas 0.16.0):

df.columns.tolist()

le dará los nombres de las columnas en una buena lista.

42

Me sorprende no haber visto esto publicado hasta ahora, así que lo dejaré aquí.

Desembalaje iterable extendido (python3.5 +): [*df]y amigos

Las generalizaciones de descompresión (PEP 448) se han introducido con Python 3.5. Entonces, las siguientes operaciones son todas posibles.

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 

Si quieres un list...

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

O, si quieres un set,

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

O, si quieres un tuple,

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

O, si desea almacenar el resultado en algún lugar,

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

... si eres el tipo de persona que convierte el café en sonidos de mecanografía, bueno, esto va a consumir tu café de manera más eficiente;)

P.S.: if performance is important, you will want to ditch the solutions above in favour of

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

This is similar to Ed Chum's answer, but updated for v0.24 where .to_numpy() is preferred to the use of .values. See this answer (by me) for more information.

Verificación visual
Como he visto esto discutido en otras respuestas, puede utilizar el desempaquetado iterable (sin necesidad de bucles explícitos).

print(*df)
A B C

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

Crítica de otros métodos

No utilice un forbucle explícito para una operación que se pueda realizar en una sola línea (las listas por comprensión están bien).

A continuación, el uso sorted(df) no conserva el orden original de las columnas. Para eso, deberías usar list(df)en su lugar.

A continuación, list(df.columns)y list(df.columns.values)son sugerencias deficientes (a partir de la versión actual, v0.24). Tanto Index(devuelto desde df.columns) como las matrices NumPy (devuelto por df.columns.values) definen un .tolist()método que es más rápido y más idiomático.

Por último, la enumeración, es decir, list(df)solo debe usarse como una alternativa concisa a los métodos antes mencionados para python <= 3.4 donde el desempaquetado extendido no está disponible.

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

Para enumerar las columnas de un marco de datos mientras está en modo depurador, use una lista de comprensión:

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

Por cierto, puede obtener una lista ordenada simplemente usando sorted:

>>> sorted(my_dataframe)
['cap', 'gdp', 'y']
2
  • ¿ list(df)Funcionaría eso solo con marcos de datos de aumento automático? ¿O funciona para todos los marcos de datos? alvas 13 de enero de 2016 a las 6:49
  • 2
    Debería funcionar para todos. Sin embargo, cuando está en el depurador, debe usar una lista de comprensión [c for c in df]. Alexander 13 de enero de 2016 a las 7:28
25

Eso está disponible como my_dataframe.columns.

2
  • 1
    Y explícitamente como una lista porheader_list = list(my_dataframe.columns)yeliabsalohcin 5 de septiembre de 2017 a las 12:59
  • 1
    ^ O mejor aún: df.columns.tolist(). cs95 3/04/19 a las 9:52
19

Es interesante, pero df.columns.values.tolist()es casi 3 veces más rápido, df.columns.tolist()pero pensé que eran lo mismo:

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
1
  • 2
    Los tiempos ya se han cubierto en esta respuesta . La razón de la discrepancia es porque .valuesdevuelve la matriz numpy subyacente, y hacer algo con numpy es casi siempre más rápido que hacer lo mismo con pandas directamente. cs95 3 abr 19 a las 9:48
19

Un DataFrame sigue la convención similar a un dictado de iterar sobre las "claves" de los objetos.

my_dataframe.keys()

Crear una lista de claves / columnas: método de objeto to_list()y forma pitónica

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

La iteración básica en un DataFrame devuelve etiquetas de columna

[column for column in my_dataframe]

No convierta un DataFrame en una lista, solo para obtener las etiquetas de las columnas. No deje de pensar mientras busca ejemplos de código convenientes.

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
  • 2
    Mis pruebas muestran que df.columnses mucho más rápido que df.keys(). No estoy seguro de por qué tienen una función y un atributo para lo mismo (bueno, no es la primera vez que veo 10 formas diferentes de hacer algo en pandas). cs95 3 abr 19 a las 9:45
  • 1
    La intención de mi respuesta fue mostrar un par de formas de consultar etiquetas de columna desde un DataFrame y resaltar un antipatrón de rendimiento. Sin embargo, me gustan sus comentarios y voté a favor de su respuesta reciente, ya que brindan valor desde el punto de vista de la ingeniería de software. Sascha Gottfried 9/04/19 a las 10:05
14

En el cuaderno

Para la exploración de datos en el cuaderno IPython, mi forma preferida es esta:

sorted(df)

Lo que producirá una lista ordenada alfabéticamente fácil de leer.

En un repositorio de código

En el código, lo encuentro más explícito para hacer

df.columns

Porque les dice a otros que leen su código lo que está haciendo.

2
  • sorted(df)cambia de orden. Úselo con precaución. cs95 3 abr 19 a las 9:45
  • @coldspeed Sin embargo, menciono esto "Lo que producirá una lista ordenada alfabéticamente fácil de leer". firelynx 3/04/19 a las 11:48
10
%%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

como respondió Simeon Visser ... podrías hacer

list(my_dataframe.columns.values) 

o

list(my_dataframe) # for less typing.

Pero creo que el punto óptimo es:

list(my_dataframe.columns)

Es explícito, al mismo tiempo no innecesariamente largo.

1
  • "Es explícito, al mismo tiempo no innecesariamente largo". Estoy en desacuerdo. Llamar listno tiene ningún mérito a menos que lo haga dfdirectamente (por ejemplo, la concisión). Acceder al .columnsatributo devuelve un Indexobjeto que tiene un tolist()método definido, y llamarlo es más idiomático que enumerar el Index. Mezclar expresiones idiomáticas solo para completarlo no es una gran idea. Lo mismo ocurre con la lista de la matriz de la que obtiene .values. cs95 3 abr 19 a las 9:42
3

Para una revisión visual rápida, ordenada, intente esto:

for col in df.columns:
    print col
2

Creo que la pregunta merece una explicación adicional.

Como señaló @fixxxer, la respuesta depende de la versión de pandas que esté utilizando en su proyecto. Que puedes conseguir con el pd.__version__comando.

Si por alguna razón es como yo (en debian jessie utilizo 0.14.1) usando una versión anterior de pandas que 0.16.0, entonces necesita usar:

df.keys().tolist()porque todavía no hay un df.columnsmétodo implementado.

La ventaja de este método de claves es que funciona incluso en la versión más nueva de pandas, por lo que es más universal.

1
  • La desventaja de keys () es que es una llamada a función en lugar de una búsqueda de atributos, por lo que siempre será más lento. Por supuesto, con accesos de tiempo constantes, a nadie le importan diferencias como estas, pero creo que vale la pena mencionarlo de todos modos; df.columns es ahora un modismo más universalmente aceptado para acceder a los encabezados. cs95 4 abr 19 a las 21:00
1
n = []
for i in my_dataframe.columns:
    n.append(i)
print n
3
  • 6
    reemplácelo con una lista de comprensión. Sascha Gottfried 23 de enero de 2014 a las 16:22
  • 4
    cambie sus primeras 3 líneas a[n for n in dataframe.columns]Anton Protopopov 4 dic 2015 a las 21:31
  • ¿Por qué querría pasar por todos estos problemas para una operación que puede hacer fácilmente en una sola línea? cs95 3 abr 19 a las 9:36
0

Aunque la solución que se proporcionó anteriormente es buena. También esperaría que algo como frame.column_names () sea una función en pandas, pero como no lo es, tal vez sería bueno usar la siguiente sintaxis. De alguna manera conserva la sensación de que estás usando pandas de manera adecuada llamando a la función "tolist": frame.columns.tolist ()

frame.columns.tolist() 
0
0

Si el DataFrame tiene un índice o un índice múltiple y también desea que se incluyan como nombres de columna:

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

Evita llamar a reset_index () que tiene un impacto de rendimiento innecesario para una operación tan simple.

Me he encontrado con la necesidad de esto con más frecuencia porque estoy transfiriendo datos desde bases de datos donde el índice del marco de datos se asigna a una clave principal / única, pero en realidad es solo otra "columna" para mí. Probablemente tendría sentido que los pandas tuvieran un método incorporado para algo como esto (es totalmente posible que me lo haya perdido).