Obtener la lista de encabezados de columna de pandas DataFrame


1017

Quiero obtener una lista de los encabezados de columna de un DataFrame de pandas. El DataFrame vendrá de la entrada del usuario, así 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

Me gustaría obtener una lista como esta:

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

Respuestas:


1648

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)

42
¿Por qué este documento no tiene columnscomo atributo?
Tjorriemorrie

@Tjorriemorrie: No estoy seguro, puede que tenga que ver con la forma en que generan automáticamente su documentación. Sin embargo, se menciona en otros lugares: pandas.pydata.org/pandas-docs/stable/…
Simeon Visser

8
Hubiera esperado algo así df.column_names(). ¿Esta respuesta sigue siendo correcta o está desactualizada?
alvas

1
@alvas hay varias otras formas de hacerlo (ver otras respuestas en esta página), pero que yo sepa, no hay un método en el marco de datos directamente para producir la lista.
Simeon Visser

19
Es importante destacar que esto conserva el orden de las columnas.
WindChimes

405

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 en el 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)

44
No rechazó la votación, pero quiero explicar: no confíe en los detalles de implementación, use la "interfaz pública" de DataFrame. Piensa en la belleza de df.keys ()
Sascha Gottfried

3
@SaschaGottfried la implementación del DataFrameiterable no ha cambiado desde el primer día: pandas.pydata.org/pandas-docs/stable/basics.html#iteration . El iterable devuelto por un DataFrame siempre ha sido las columnas, por lo for col in df:que siempre debe comportarse de la misma manera a menos que los desarrolladores tengan una fusión, por lo que list(df)es y debería ser un método válido. Tenga en cuenta que df.keys()está llamando a la implementación interna de la estructura de tipo dict que devuelve las claves que son las columnas. Los votos negativos inexplicables son el daño colateral que se espera en SO, así que no se preocupe
EdChum

Me refería a los detalles de implementación del columnsatributo. Hace una hora leí acerca de la Ley de Deméter que promovía que la persona que llama no debería depender de navegar por el modelo de objeto interno. list(df)hace conversión de tipo explícito. Efecto secundario notable: el tiempo de ejecución y el consumo de memoria aumentan con el df.keys()método de tamaño de trama de datos es parte de la naturaleza dict-like de a DataFrame. Hecho notable: el tiempo de ejecución df.keys()es bastante constante independientemente del tamaño del marco de datos, parte de la responsabilidad de los desarrolladores de pandas.
Sascha Gottfried

1
@SaschaGottfried Puedo agregar esto a mi respuesta y acreditarlo ya que nadie más lo ha incluido
EdChum

1
Puedo ver el valor en la respuesta dada, así como en los comentarios, no es necesario cambiar nada.
Sascha Gottfried

89

Hice algunas pruebas rápidas, y quizás 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!)


47

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.


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

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

>>> [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']

¿ list(df)Funcionaría solo con marcos de datos de aumento automático? ¿O funciona para todos los marcos de datos?
alvas

2
Debería funcionar para todos. Sin embargo, cuando está en el depurador, necesita usar una lista de comprensión [c for c in df].
Alexander el

25

Sorprendido, no he visto esto publicado hasta ahora, así que lo dejaré aquí.

Desempaquetado Iterable Extendido (python3.5 +): [*df]y Amigos

Las generalizaciones de desempaque (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 consumirá tu café de manera más eficiente;)

PD: si el rendimiento es importante, querrás deshacerte de las soluciones anteriores a favor de

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

Esto es similar a la respuesta de Ed Chum , pero actualizado para v0.24, donde .to_numpy()se prefiere el uso de .values. Vea esta respuesta (por mí) para más información.

Verificación visual
Como he visto esto discutido en otras respuestas, puede utilizar desempaquetar 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 use un explícito for bucle para una operación que se puede hacer en una sola línea (las comprensiones de la lista están bien).

A continuación, el uso sorted(df) no conserva el orden original de las columnas. Para eso, debes usarlist(df) en lugar.

A continuación, list(df.columns)y list(df.columns.values)son sugerencias pobres (a partir de la versión actual, v0.24). Ambas matrices Index(devueltas de df.columns) y NumPy (devueltas por df.columns.values) definen.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 desembalaje extendido no está disponible.


24

Eso está disponible como my_dataframe.columns.


1
Y explícitamente como una lista porheader_list = list(my_dataframe.columns)
yeliabsalohcin

^ O mejor aún: df.columns.tolist().
cs95

18

Es interesante, pero df.columns.values.tolist()es casi 3 veces más rápido, df.columns.tolist()pero pensé que son 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

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 los pandas directamente.
cs95

17

Un DataFrame sigue la convención tipo dict 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 columna. No deje de pensar mientras busca ejemplos de códigos 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
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 la misma cosa (bueno, no es la primera vez que veo 10 formas diferentes de hacer algo en pandas).
cs95

1
La intención de mi respuesta fue mostrar un par de formas de consultar las etiquetas de columna de un DataFrame y resaltar un antipatrón de rendimiento. Sin embargo, me agradan sus comentarios y voté por su respuesta reciente, ya que proporcionan valor desde el punto de vista de la ingeniería de software.
Sascha Gottfried

14

En el cuaderno

Para la exploración de datos en el cuaderno de 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 me parece más explícito hacer

df.columns

Porque le dice a otros que leen tu código lo que estás haciendo.


sorted(df)cambia el orden Usar con precaución.
cs95

@coldspeed. Sin embargo, menciono esto: "Lo que producirá una lista ordenada alfabéticamente fácil de leer".
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

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

list(my_dataframe.columns.values) 

o

list(my_dataframe) # for less typing.

Pero creo que el mejor punto es:

list(my_dataframe.columns)

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


"Es explícito, al mismo tiempo, no innecesariamente largo". Estoy en desacuerdo. Llamar listno tiene mérito a menos que lo llame dfdirectamente (por ejemplo, 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 por completar no es una gran idea. Lo mismo ocurre con la lista de la matriz que obtiene .values.
cs95

3

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

for col in df.columns:
    print col

3

Esto nos da los nombres de las columnas en una lista:

list(my_dataframe.columns)

También se puede usar otra función llamada tolist ():

my_dataframe.columns.tolist()

Esto ya ha sido cubierto en otras respuestas. Su primera solución también mezcla modismos, lo cual no es una gran idea. Ver mi comentario bajo otra respuesta.
cs95

2

Siento 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 conpd.__version__ comando.

Si por alguna razón como yo (en Debian Jessica uso 0.14.1) usando una versión anterior de pandas que no sea 0.16.0, entonces necesita usar:

df.keys().tolist() porque no hay df.columns método implementado.

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


La desventaja de las teclas () es que es una llamada de función en lugar de una búsqueda de atributos, por lo que siempre será más lenta. Por supuesto, con accesos de tiempo constantes, a nadie realmente le importan diferencias como estas, pero creo que vale la pena mencionarlo de todos modos; df.columns es ahora un idioma más universalmente aceptado para acceder a los encabezados.
cs95

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

66
reemplácelo con una lista de comprensión.
Sascha Gottfried

44
cambie sus primeras 3 líneas a[n for n in dataframe.columns]
Anton Protopopov

¿Por qué querría pasar por todos estos problemas para una operación que puede hacer fácilmente en una sola línea?
cs95

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á utilizando los pandas de manera adecuada llamando a la función "tolist": frame.columns.tolist ()

frame.columns.tolist() 

0

Si el DataFrame tiene un índice o MultiIndex y desea incluirlos también 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 que necesito esto más a menudo porque estoy transfiriendo datos de bases de datos donde el índice del marco de datos se asigna a una clave primaria / única, pero en realidad es solo otra "columna" para mí. Probablemente tendría sentido que los pandas tengan un método incorporado para algo como esto (totalmente posible, me lo he perdido).


-1

Esta solución enumera todas las columnas de su objeto my_dataframe:

print(list(my_dataframe))
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.