Renomear índice do DataFrame do Pandas

142

Eu tenho um arquivo csv sem cabeçalho, com um índice DateTime. Quero renomear o nome do índice e da coluna, mas com df.rename () apenas o nome da coluna é renomeado. Erro? Estou na versão 0.12.0

In [2]: df = pd.read_csv(r'D:\Data\DataTimeSeries_csv//seriesSM.csv', header=None, parse_dates=[[0]], index_col=[0] )

In [3]: df.head()
Out[3]: 
                   1
0                   
2002-06-18  0.112000
2002-06-22  0.190333
2002-06-26  0.134000
2002-06-30  0.093000
2002-07-04  0.098667

In [4]: df.rename(index={0:'Date'}, columns={1:'SM'}, inplace=True)

In [5]: df.head()
Out[5]: 
                  SM
0                   
2002-06-18  0.112000
2002-06-22  0.190333
2002-06-26  0.134000
2002-06-30  0.093000
2002-07-04  0.098667
Mattijn
fonte
5
Para aqueles que chegam a esta pergunta em 2017, verifique esta resposta abaixo para ver uma explicação muito detalhada do rename_axismétodo.
Ted Petrou #
3
E para aqueles que não se incomodam em ler toda a boa resposta abaixo, a solução rápida é df.rename_axis("Date", axis='index', inplace=True)conforme a documentação pandas.pydata.org/pandas-docs/stable/generated/… oudf.index.names = ['Date']
tommy.carstensen

Respostas:

237

o rename método utiliza um dicionário para o índice que se aplica aos valores do índice .
Você deseja renomear para o nome do nível de índice:

df.index.names = ['Date']

Uma boa maneira de pensar sobre isso é que colunas e índice são do mesmo tipo de objeto ( IndexouMultiIndex ) e você pode trocar os dois via transposição.

Isso é um pouco confuso, pois os nomes dos índices têm um significado semelhante às colunas, então, aqui estão mais alguns exemplos:

In [1]: df = pd.DataFrame([[1, 2, 3], [4, 5 ,6]], columns=list('ABC'))

In [2]: df
Out[2]: 
   A  B  C
0  1  2  3
1  4  5  6

In [3]: df1 = df.set_index('A')

In [4]: df1
Out[4]: 
   B  C
A      
1  2  3
4  5  6

Você pode ver a renomeação no índice, o que pode alterar a valor 1:

In [5]: df1.rename(index={1: 'a'})
Out[5]: 
   B  C
A      
a  2  3
4  5  6

In [6]: df1.rename(columns={'B': 'BB'})
Out[6]: 
   BB  C
A       
1   2  3
4   5  6

Enquanto renomeia os nomes dos níveis:

In [7]: df1.index.names = ['index']
        df1.columns.names = ['column']

Nota: este atributo é apenas uma lista e você pode renomear como um entendimento / mapa da lista.

In [8]: df1
Out[8]: 
column  B  C
index       
1       2  3
4       5  6
Andy Hayden
fonte
2
Ótima resposta. Apenas um lembrete gentil de que "inplace =True", sem , df1.renamerealmente não mudaria nada.
Sarah
63

A resposta atualmente selecionada não menciona o rename_axis método que pode ser usado para renomear os níveis de índice e coluna.


O Pandas tem algumas peculiaridades quando se trata de renomear os níveis do índice. Há também um novo método DataFramerename_axis disponível para alterar os nomes do nível do índice.

Vamos dar uma olhada em um DataFrame

df = pd.DataFrame({'age':[30, 2, 12],
                       'color':['blue', 'green', 'red'],
                       'food':['Steak', 'Lamb', 'Mango'],
                       'height':[165, 70, 120],
                       'score':[4.6, 8.3, 9.0],
                       'state':['NY', 'TX', 'FL']},
                       index = ['Jane', 'Nick', 'Aaron'])

insira a descrição da imagem aqui

Este DataFrame possui um nível para cada um dos índices de linha e coluna. O índice de linha e coluna não tem nome. Vamos mudar o nome do nível do índice de linha para 'names'.

df.rename_axis('names')

insira a descrição da imagem aqui

O rename_axismétodo também tem a capacidade de alterar os nomes do nível da coluna alterando o axisparâmetro:

df.rename_axis('names').rename_axis('attributes', axis='columns')

insira a descrição da imagem aqui

Se você definir o índice com algumas das colunas, o nome da coluna se tornará o novo nome no nível do índice. Vamos acrescentar os níveis de índice ao nosso DataFrame original:

df1 = df.set_index(['state', 'color'], append=True)
df1

insira a descrição da imagem aqui

Observe como o índice original não tem nome. Ainda podemos usar, rename_axismas precisamos passar uma lista do mesmo tamanho que o número de níveis de índice.

df1.rename_axis(['names', None, 'Colors'])

insira a descrição da imagem aqui

Você pode usar Nonepara excluir efetivamente os nomes no nível do índice.


As séries funcionam da mesma forma, mas com algumas diferenças

Vamos criar uma série com três níveis de índice

s = df.set_index(['state', 'color'], append=True)['food']
s

       state  color
Jane   NY     blue     Steak
Nick   TX     green     Lamb
Aaron  FL     red      Mango
Name: food, dtype: object

Podemos usar da rename_axismesma forma como fizemos com DataFrames

s.rename_axis(['Names','States','Colors'])

Names  States  Colors
Jane   NY      blue      Steak
Nick   TX      green      Lamb
Aaron  FL      red       Mango
Name: food, dtype: object

Observe que há um pedaço extra de metadados abaixo da série chamada Name . Ao criar uma série a partir de um DataFrame, esse atributo é definido como o nome da coluna.

Podemos passar um nome de string para o renamemétodo para alterá-lo

s.rename('FOOOOOD')

       state  color
Jane   NY     blue     Steak
Nick   TX     green     Lamb
Aaron  FL     red      Mango
Name: FOOOOOD, dtype: object

Os DataFrames não possuem esse atributo e o infact gerará uma exceção se usado assim

df.rename('my dataframe')
TypeError: 'str' object is not callable

Antes do pandas 0.21, você poderia rename_axisrenomear os valores no índice e nas colunas. Foi preterido, portanto, não faça isso

Ted Petrou
fonte
1
Se você trocar df1 = df.set_index(['state', 'color'], append=True)com df1.rename_axis(['names', None, 'Colors'])?
salhin
E se eu quiser renomear "Nick" para "Nicolas"? Era isso que eu procurava quando pesquisei "renomear índice de pandas" no Google e acabei aqui. EDIT: Oh espere, a resposta aceita explica isso, simplesmente não era óbvio para mim no começo.
Ben Farmer
Bom, esta é a única resposta que pode ser usada em tarefas encadeadas!
21919 IanS
19

Para pandasversões mais recentes

df.index = df.index.rename('new name')

ou

df.index.rename('new name', inplace=True)

O último é necessário se um quadro de dados reter todas as suas propriedades.

Serge Stroobandt
fonte
18

No Pandas versão 0.13 e superior, os nomes de nível de índice são imutáveis ​​(tipo FrozenList) e não podem mais ser definidos diretamente. Você deve primeiro usar Index.rename()para aplicar os novos nomes de nível de índice ao Índice e depois DataFrame.reindex()aplicar para aplicar o novo índice ao DataFrame. Exemplos:

Para a versão Pandas <0,13

df.index.names = ['Date']

Para a versão Pandas> = 0.13

df = df.reindex(df.index.rename(['Date']))
David Smith
fonte
9
Não é verdade! Na minha versão do Pandas (0.13.1), df.index.names = ['foo'] funciona bem!
LondonRob
5
Obrigado por perceber que @LondonRob - `df.index.names = ['foo']` também funciona para mim com o Pandas 0.14. Aparentemente, isso foi quebrado apenas brevemente e incluído quando o testei.
David Smith
1
Definir nomes para um indexou columndiretamente está mudando os dois para mim (no Pandas 0.19), mas não com esse método.
24417 FooBar
8

Você também pode usar da Index.set_namesseguinte maneira:

In [25]: x = pd.DataFrame({'year':[1,1,1,1,2,2,2,2],
   ....:                   'country':['A','A','B','B','A','A','B','B'],
   ....:                   'prod':[1,2,1,2,1,2,1,2],
   ....:                   'val':[10,20,15,25,20,30,25,35]})

In [26]: x = x.set_index(['year','country','prod']).squeeze()

In [27]: x
Out[27]: 
year  country  prod
1     A        1       10
               2       20
      B        1       15
               2       25
2     A        1       20
               2       30
      B        1       25
               2       35
Name: val, dtype: int64
In [28]: x.index = x.index.set_names('foo', level=1)

In [29]: x
Out[29]: 
year  foo  prod
1     A    1       10
           2       20
      B    1       15
           2       25
2     A    1       20
           2       30
      B    1       25
           2       35
Name: val, dtype: int64
LondonRob
fonte
2
Isso pode funcionar para um multiIndex? MultiIndex(levels=[['A', 'B', 'C', 'D', 'E', 'F'], ['Y', 'Z']], labels=[[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5], [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]], names=['Portfolio', None])É possível renomear o Nonepara measures?
ctrl-alt-delete
2

Se você deseja usar o mesmo mapeamento para renomear colunas e índice, você pode:

mapping = {0:'Date', 1:'SM'}
df.index.names = list(map(lambda name: mapping.get(name, name), df.index.names))
df.rename(columns=mapping, inplace=True)
danio
fonte
0
df.index.rename('new name', inplace=True)

É o único que faz o trabalho para mim (pandas 0.22.0).
Sem o inplace = True, o nome do índice não está definido no meu caso.

Jan H.
fonte
0

você pode usar indexe columnsatributos de pandas.DataFrame. NOTA: o número de elementos da lista deve corresponder ao número de linhas / colunas.

#       A   B   C
# ONE   11  12  13
# TWO   21  22  23
# THREE 31  32  33

df.index = [1, 2, 3]
df.columns = ['a', 'b', 'c']
print(df)

#     a   b   c
# 1  11  12  13
# 2  21  22  23
# 3  31  32  33
nucsit026
fonte