Quiero obtener una lista de los encabezados de columna de un Pandas DataFrame. El DataFrame provendrá 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']
respuesta

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)

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

my_dataframe.columns.values.tolist()

.columnsdevuelve un Index, .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 aquellos que odian escribir, pueden llamar lista df, así:

list(df)

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

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

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.

Desempaquetado Iterable Extendido (Python 3.5+): [*df]y Amigos

Las generalizaciones de desempaquetado (PEP 448) se han introducido con Python 3.5. Por lo tanto, 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 escritura, 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.

Comprobación visual

Como he visto esto discutido en otras respuestas, puede usar 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 puede realizar en una sola línea ( las listas de comprensión están bien).

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

Siguiente, list(df.columns)y list(df.columns.values)son sugerencias pobres (a partir de la versión actual, v0.24). Ambos Index(devueltos por df.columns) y matrices NumPy (devueltos por df.columns.values) definen .tolist()un método que es más rápido y más idiomático.

Por último, la lista, es decir, list(df)solo debe usarse como una alternativa concisa a los métodos mencionados anteriormente para Python 3.4 o versiones anteriores donde el desempaquetado extendido no está disponible.

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

Eso está disponible como my_dataframe.columns.

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

my_dataframe.keys()

Cree una lista de claves/columnas - método de objeto to_list()y la forma Pythonic:

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)

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

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

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 me parece más explícito hacer

df.columns

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

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

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

for col in df.columns:
    print col

Como respondió Simeon Visser , podrías hacer

list(my_dataframe.columns.values)

o

list(my_dataframe) # For less typing.

Pero creo que la mayoría del punto dulce es:

list(my_dataframe.columns)

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

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 con pd.__version__mando.

Si por alguna razón eres como yo (en Debian 8 (Jessie) uso 0.14.1) usando una versión anterior de Pandas que 0.16.0, entonces necesitas usar:

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

La ventaja de este método de claves es que funciona incluso en versiones más nuevas de Pandas, por lo que es más universal.

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

Si el DataFrame tiene un índice o un índice múltiple 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 encontré con la necesidad de esto con más frecuencia porque estoy transfiriendo datos de 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 (totalmente posible que me lo haya perdido).

La opción más sencilla sería: list(my_dataframe.columns)omy_dataframe.columns.tolist()

No hay necesidad de las cosas complejas anteriores :)

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

frame.columns.tolist()
import pandas as pd

# create test dataframe
df = pd.DataFrame('x', columns=['A', 'B', 'C'], index=range(2))

list(df.columns)

Devoluciones

['A', 'B', 'C']

listHeaders = [colName para colName en my_dataframe]