Cambiar el nombre del índice de marco de datos de pandas

142

Tengo un archivo csv sin encabezado, con un índice DateTime. Quiero cambiar el nombre del índice y el nombre de la columna, pero con df.rename () solo se cambia el nombre de la columna. ¿Insecto? Estoy en la versión 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
fuente
55
Para aquellos que lleguen a esta pregunta en 2017, verifique esta respuesta a continuación para ver una explicación muy detallada del rename_axismétodo.
Ted Petrou
3
Y para aquellos que no pueden molestarse en leer toda la buena respuesta a continuación, la solución rápida es df.rename_axis("Date", axis='index', inplace=True)según la documentación pandas.pydata.org/pandas-docs/stable/generated/… odf.index.names = ['Date']
tommy.carstensen

Respuestas:

237

El renamemétodo toma un diccionario para el índice que se aplica a los valores del índice .
Desea cambiar el nombre al nombre del nivel de índice:

df.index.names = ['Date']

Una buena manera de pensar en esto es que las columnas y el índice son el mismo tipo de objeto ( Indexo MultiIndex), y puede intercambiar los dos mediante transposición.

Esto es un poco confuso ya que los nombres de índice tienen un significado similar a las columnas, así que aquí hay algunos ejemplos más:

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

Puede ver el cambio de nombre en el índice, que puede cambiar el 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

Mientras renombra los nombres de nivel:

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

Nota: este atributo es solo una lista, y puede cambiar el nombre como una lista de comprensión / mapa.

In [8]: df1
Out[8]: 
column  B  C
index       
1       2  3
4       5  6
Andy Hayden
fuente
2
Gran respuesta. Solo un suave recordatorio de que sin eso "inplace =True", df1.renamerealmente no cambiaría nada.
Sarah
63

La respuesta actualmente seleccionada no menciona el rename_axismétodo que se puede usar para cambiar el nombre del índice y los niveles de columna.


Pandas tiene algunas peculiaridades a la hora de cambiar el nombre de los niveles del índice. También hay un nuevo método DataFrame rename_axisdisponible para cambiar los nombres de nivel de índice.

Echemos un vistazo a un 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'])

ingrese la descripción de la imagen aquí

Este DataFrame tiene un nivel para cada uno de los índices de fila y columna. Tanto el índice de fila como el de columna no tienen nombre. Cambiemos el nombre del nivel de índice de la fila a 'nombres'.

df.rename_axis('names')

ingrese la descripción de la imagen aquí

El rename_axismétodo también tiene la capacidad de cambiar los nombres de nivel de columna cambiando el axisparámetro:

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

ingrese la descripción de la imagen aquí

Si configura el índice con algunas de las columnas, el nombre de la columna se convertirá en el nuevo nombre del nivel de índice. Anexemos niveles de índice a nuestro DataFrame original:

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

ingrese la descripción de la imagen aquí

Observe cómo el índice original no tiene nombre. Todavía podemos usar, rename_axispero necesitamos pasarle una lista de la misma longitud que el número de niveles de índice.

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

ingrese la descripción de la imagen aquí

Puede usar Nonepara eliminar efectivamente los nombres de nivel de índice.


Las series funcionan de manera similar pero con algunas diferencias

Creemos una serie con tres niveles 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 de rename_axismanera similar a como lo hicimos con 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 hay una pieza adicional de metadatos debajo de la serie llamada Name. Al crear una serie a partir de un marco de datos, este atributo se establece en el nombre de la columna.

Podemos pasar un nombre de cadena al renamemétodo para cambiarlo

s.rename('FOOOOOD')

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

Los marcos de datos no tienen este atributo y, de hecho, generará una excepción si se usa así

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

Antes de pandas 0.21, podría haber usado rename_axispara cambiar el nombre de los valores en el índice y las columnas. Ha quedado en desuso, así que no hagas esto

Ted Petrou
fuente
1
¿Deberías intercambiar df1 = df.set_index(['state', 'color'], append=True)con df1.rename_axis(['names', None, 'Colors'])?
salhin
¿Qué pasa si quiero cambiar el nombre de "Nick" a "Nicolas"? Eso era lo que estaba buscando cuando busqué en Google "cambiar el nombre del índice de pandas" y terminé aquí. EDITAR: Oh, espera, la respuesta aceptada explica eso, simplemente no era obvio para mí al principio.
Ben Farmer
¡Agradable, esta es la única respuesta que se puede usar en tareas encadenadas!
IanS
19

Para pandasversiones mas nuevas

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

o

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

Esto último es necesario si un marco de datos debe conservar todas sus propiedades.

Serge Stroobandt
fuente
18

En Pandas versión 0.13 y superior, los nombres de nivel de índice son inmutables (tipo FrozenList) y ya no se pueden establecer directamente. Primero debe usar Index.rename()para aplicar los nuevos nombres de nivel de índice al Índice y luego usar DataFrame.reindex()para aplicar el nuevo índice al Marco de datos. Ejemplos:

Para la versión de Pandas <0.13

df.index.names = ['Date']

Para la versión de Pandas> = 0.13

df = df.reindex(df.index.rename(['Date']))
David Smith
fuente
9
¡No es verdad! ¡En mi versión de Pandas (0.13.1) df.index.names = ['foo'] funciona bien!
LondonRob
55
Gracias por notar que @LondonRob - `df.index.names = ['foo']` también funciona para mí con Pandas 0.14. Aparentemente, eso solo se rompió brevemente y se incluyó cuando lo probé.
David Smith
1
Establecer nombres para cualquiera indexo columndirectamente está cambiando para mí (en Pandas 0.19), pero no con este método.
FooBar
8

También puede usar Index.set_nameslo siguiente:

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
fuente
2
¿Esto puede funcionar para un 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])¿Es posible cambiar el nombre de Nonea measures?
ctrl-alt-delete
2

Si desea utilizar la misma asignación para cambiar el nombre de las columnas y el índice, puede hacer lo siguiente:

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
fuente
0
df.index.rename('new name', inplace=True)

Es el único que hace el trabajo por mí (pandas 0.22.0).
Sin inplace = True, el nombre del índice no está configurado en mi caso.

Jan H.
fuente
0

puedes usar indexy columnsatributos de pandas.DataFrame. NOTA: el número de elementos de la lista debe coincidir con el número de filas / columnas.

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