Obter lista dos cabeçalhos de coluna do pandas DataFrame

1015

Quero obter uma lista dos cabeçalhos das colunas de um DataFrame do pandas. O DataFrame virá da entrada do usuário, portanto não saberei quantas colunas haverá ou como serão chamadas.

Por exemplo, se eu receber um 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

Eu gostaria de obter uma lista como esta:

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

Respostas:

1647

Você pode obter os valores como uma lista fazendo:

list(my_dataframe.columns.values)

Além disso, você pode simplesmente usar: (como mostrado na resposta de Ed Chum ):

list(my_dataframe)
Simeon Visser
fonte
42
Por que este documento não tem columnscomo atributo?
Tjorriemorrie 21/11
@Tjorriemorrie: Não tenho certeza, pode ter a ver com a maneira como eles geram automaticamente sua documentação. Porém, é mencionado em outros lugares: pandas.pydata.org/pandas-docs/stable/…
Simeon Visser
8
Eu teria esperado algo parecido df.column_names(). Essa resposta ainda está correta ou está desatualizada?
alvas
1
@ alvas existem várias outras maneiras de fazer isso (consulte outras respostas nesta página), mas até onde eu sei, não existe um método no dataframe diretamente para produzir a lista.
Simeon Visser
19
Importante, isso preserva a ordem das colunas.
WindChimes
402

Existe um método embutido que é o mais eficiente:

my_dataframe.columns.values.tolist()

.columnsretorna um índice, .columns.valuesretorna uma matriz e isso tem uma função auxiliar .tolistpara retornar uma lista.

Se o desempenho não for tão importante para você, os Indexobjetos definem um .tolist()método que você pode chamar diretamente:

my_dataframe.columns.tolist()

A diferença no desempenho é óbvia:

%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 aqueles que odeiam a digitação, você pode apenas chamar liston df, assim:

list(df)
EdChum
fonte
4
Não votou negativamente, mas quer explicar: não confie nos detalhes da implementação, use a "interface pública" do DataFrame. Pense sobre a beleza da df.keys ()
Sascha Gottfried
3
@SaschaGottfried a implementação do DataFrameiterável não mudou desde o primeiro dia: pandas.pydata.org/pandas-docs/stable/basics.html#iteration . O iterável retornado de um DataFrame sempre foi as colunas; portanto, esse procedimento for col in df:deve sempre se comportar da mesma forma, a menos que os desenvolvedores tenham um colapso, list(df)e ainda deve ser um método válido. Observe que df.keys()está chamando para a implementação interna da estrutura dict-like retornando as chaves que são as colunas. Downvotes inexplicáveis é o efeito colateral de se esperar no SO então não se preocupe
EdChum
Eu estava me referindo aos detalhes de implementação do columnsatributo. Há uma hora, li sobre a Lei de Demeter promovendo que o chamador não deveria depender da navegação no modelo de objeto interno. list(df)faz conversão de tipo explícita. Efeito colateral notável: o tempo de execução e o consumo de memória aumentam com o df.keys()método de tamanho do quadro de dados faz parte da natureza ditada de a DataFrame. Fato notável: o tempo de execução df.keys()é bastante constante, independentemente do tamanho do quadro de dados - parte da responsabilidade dos desenvolvedores do pandas.
Sascha Gottfried
1
@SaschaGottfried I pode adicionar este para a minha resposta e de crédito que você vê como ninguém incluiu este
EdChum
1
Eu posso ver o valor na resposta dada e nos comentários - não há necessidade de alterar nada.
Sascha Gottfried
89

Fiz alguns testes rápidos e, talvez sem surpresa, a versão incorporada dataframe.columns.values.tolist()é a mais 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

(Eu ainda gosto muito do list(dataframe)mesmo, então, obrigado EdChum!)

tegan
fonte
47

Torna-se ainda mais simples (pelos pandas 0.16.0):

df.columns.tolist()

fornecerá os nomes das colunas em uma boa lista.

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

Para listar as colunas de um quadro de dados no modo depurador, use uma compreensão da lista:

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

A propósito, você pode obter uma lista classificada simplesmente usando sorted:

>>> sorted(my_dataframe)
['cap', 'gdp', 'y']
Alexander
fonte
Isso list(df)funcionaria apenas com quadros de dados de incremento automático? Ou funciona para todos os quadros de dados?
alvas
2
Deveria funcionar para todos. Quando você está no depurador, no entanto, você precisa usar uma compreensão de lista [c for c in df].
Alexander
25

Surpreso por não ter visto isso publicado até agora, então vou deixar isso aqui.

Descompactação Iterável Estendida (python3.5 +): [*df]e Amigos

Generalizações de desempacotamento (PEP 448) foram introduzidas com o Python 3.5. Portanto, as seguintes operações são possíveis.

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 você quer um list....

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

Ou, se você quiser um set,

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

Ou, se você quiser um tuple,

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

Ou, se você deseja armazenar o resultado em algum lugar,

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

... se você é o tipo de pessoa que converte café em sons de digitação, bem, isso consumirá seu café com mais eficiência;)

PS: se o desempenho for importante, você desejará abandonar as soluções acima em favor de

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

Isso é semelhante à resposta de Ed Chum , mas atualizado para a v0.24, onde .to_numpy()é preferível o uso de .values. Veja esta resposta (por mim) para mais informações.

Verificação visual
Como eu já vi isso discutido em outras respostas, você pode utilizar a descompactação iterável (sem necessidade de loops explícitos).

print(*df)
A B C

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

Crítica de outros métodos

Não use um forloop explícito para uma operação que possa ser feita em uma única linha (a compreensão da lista está correta).

Em seguida, o uso sorted(df) não preserva a ordem original das colunas. Para isso, você deve usar em seu list(df)lugar.

A seguir, list(df.columns)e list(df.columns.values)há sugestões ruins (na versão atual, v0.24). As matrizes Index(retornadas de df.columns) e NumPy (retornadas por df.columns.values) definem o .tolist()método que é mais rápido e mais idiomático.

Por fim, a listagem, por exemplo, list(df)deve ser usada apenas como uma alternativa concisa aos métodos acima mencionados para python <= 3.4, onde a descompactação estendida não está disponível.

cs95
fonte
24

Está disponível como my_dataframe.columns.

BrenBarn
fonte
1
E explicitamente como uma lista porheader_list = list(my_dataframe.columns)
yeliabsalohcin 5/17/17
^ Ou melhor ainda: df.columns.tolist().
cs95
18

É interessante, mas df.columns.values.tolist()é quase três vezes mais rápido, df.columns.tolist()mas eu pensei que eles são os mesmos:

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
fonte
2
Os horários já foram abordados nesta resposta . O motivo da discrepância é que .valuesretorna a matriz numpy subjacente e fazer algo com numpy quase sempre é mais rápido do que fazer a mesma coisa diretamente com os pandas.
cs95
17

Um DataFrame segue a convenção do tipo ditado de iterar sobre as "chaves" dos objetos.

my_dataframe.keys()

Crie uma lista de chaves / colunas - método de objeto to_list()e maneira pitônica

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

A iteração básica em um DataFrame retorna rótulos de coluna

[column for column in my_dataframe]

Não converta um DataFrame em uma lista, apenas para obter os rótulos da coluna. Não pare de pensar enquanto procura exemplos 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)
Sascha Gottfried
fonte
2
Meus testes mostram que df.columnsé muito mais rápido que df.keys(). Não sei por que eles têm uma função e um atributo para a mesma coisa (bem, não é a primeira vez que vejo 10 maneiras diferentes de fazer algo em pandas).
cs95
1
A intenção da minha resposta foi mostrar algumas maneiras de consultar os rótulos das colunas de um DataFrame e destacar um antipadrão de desempenho. No entanto, eu gosto dos seus comentários e votei na sua resposta recente - pois eles fornecem valor do ponto de vista da engenharia de software.
Sascha Gottfried
14

No caderno

Para exploração de dados no notebook IPython, minha maneira preferida é a seguinte:

sorted(df)

O que produzirá uma lista ordenada alfabeticamente de fácil leitura.

Em um repositório de código

No código, acho mais explícito fazer

df.columns

Porque diz aos outros que leem seu código o que você está fazendo.

firelynx
fonte
sorted(df)muda a ordem. Use com cuidado.
cs95
@ Coldspeed Eu mencionei isso no entanto "O que produzirá uma lista fácil de ler em ordem alfabética".
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
fonte
3

respondido por Simeon Visser ... você poderia fazer

list(my_dataframe.columns.values) 

ou

list(my_dataframe) # for less typing.

Mas acho que mais o ponto ideal é:

list(my_dataframe.columns)

É explícito, ao mesmo tempo não desnecessariamente longo.

Vivek
fonte
"É explícito, ao mesmo tempo não desnecessariamente longo." Discordo. A chamada listnão tem mérito, a menos que você a esteja chamando dfdiretamente (por exemplo, concisão). O acesso ao .columnsatributo retorna um Indexobjeto que possui um tolist()método definido e a chamada é mais idiomática do que listar o Index. Misturar expressões idiomáticas apenas por uma questão de completude não é uma ótima idéia. O mesmo vale para listar a matriz que você obtém .values.
cs95
3

Para uma verificação rápida, clara e visual, tente o seguinte:

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

Isso nos dá os nomes das colunas em uma lista:

list(my_dataframe.columns)

Outra função chamada tolist () também pode ser usada:

my_dataframe.columns.tolist()
Harikrishna
fonte
Isso já foi abordado em outras respostas. Sua primeira solução também combina idiomas, o que não é uma ótima idéia. Veja meu comentário em outra resposta.
cs95
2

Sinto que a pergunta merece uma explicação adicional.

Como o @fixxxer observou, a resposta depende da versão do pandas que você está usando no seu projeto. Que você pode obter com o pd.__version__comando.

Se você, por algum motivo como eu (no debian jessie, uso 0.14.1) usando a versão mais antiga do pandas que a 0.16.0, então você precisa usar:

df.keys().tolist()porque ainda não existe um df.columnsmétodo implementado.

A vantagem desse método de chaves é que ele funciona mesmo na versão mais recente do pandas, por isso é mais universal.

StefanK
fonte
O resultado de keys () é que é uma chamada de função, e não uma pesquisa de atributo, por isso sempre será mais lento. Claro, com acessos constantes, ninguém se importa com diferenças como essas, mas acho que vale a pena mencionar de qualquer maneira; O df.columns agora é um idioma aceito universalmente para acessar cabeçalhos.
cs95
1
n = []
for i in my_dataframe.columns:
    n.append(i)
print n
user21988
fonte
6
substitua-o por uma compreensão da lista.
Sascha Gottfried
4
altere suas 3 primeiras linhas para[n for n in dataframe.columns]
Anton Protopopov
Por que você gostaria de passar por todo esse problema para uma operação que você pode fazer facilmente em uma única linha?
cs95
0

Mesmo que a solução fornecida acima seja boa. Eu também esperaria que algo como frame.column_names () fosse uma função no pandas, mas como não é, talvez seja bom usar a seguinte sintaxe. De alguma forma, preserva a sensação de que você está usando pandas de maneira adequada, chamando a função "tolist": frame.columns.tolist ()

frame.columns.tolist() 
Igor Jakovljevic
fonte
0

Se o DataFrame tiver um índice ou um MultiIndex e você desejar incluí-los também como nomes de colunas:

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

Evita chamar reset_index () que possui um desempenho desnecessário para uma operação tão simples.

Passei a precisar disso com mais frequência porque estou transferindo dados de bancos de dados nos quais o índice do quadro de dados é mapeado para uma chave primária / única, mas na verdade é apenas mais uma "coluna" para mim. Provavelmente faria sentido que os pandas tivessem um método embutido para algo assim (totalmente possível que eu tenha perdido).

totalhack
fonte
-1

Esta solução lista todas as colunas do seu objeto my_dataframe:

print(list(my_dataframe))
Sunitha G
fonte