Rinomina l'indice Pandas DataFrame


142

Ho un file CSV senza intestazione, con un indice DateTime. Voglio rinominare l'indice e il nome della colonna, ma con df.rename () viene rinominato solo il nome della colonna. Bug? Sono sulla versione 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

5
Per chi arriva a questa domanda nel 2017, controlla questa risposta qui sotto per vedere una spiegazione molto dettagliata del rename_axismetodo.
Ted Petrou,

3
E per coloro che non possono essere disturbati a leggere l'intera buona risposta di seguito, la soluzione rapida è df.rename_axis("Date", axis='index', inplace=True)come nella documentazione pandas.pydata.org/pandas-docs/stable/generated/… oppuredf.index.names = ['Date']
tommy.carstensen il

Risposte:


237

Il renamemetodo utilizza un dizionario per l'indice che si applica ai valori di indice .
Vuoi rinominare il nome del livello di indice:

df.index.names = ['Date']

Un buon modo di pensare a questo è che le colonne e l'indice sono dello stesso tipo di oggetto ( Indexo MultiIndex), e puoi scambiare i due tramite trasposizione.

Questo è un po 'confuso poiché i nomi degli indici hanno un significato simile alle colonne, quindi ecco alcuni altri esempi:

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

È possibile visualizzare la ridenominazione nell'indice, che può modificare il valore 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

Rinominando i nomi dei livelli:

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

Nota: questo attributo è solo un elenco e potresti rinominare come comprensione / mappa di un elenco.

In [8]: df1
Out[8]: 
column  B  C
index       
1       2  3
4       5  6

2
Bella risposta. Solo un gentile promemoria che senza "inplace =True", df1.renamenon cambierebbe davvero nulla.
Sarah,

63

La risposta attualmente selezionata non menziona il rename_axismetodo che può essere utilizzato per rinominare i livelli di indice e colonna.


Panda ha qualche stranezza quando si tratta di rinominare i livelli dell'indice. È inoltre disponibile un nuovo metodo DataFrame rename_axisper modificare i nomi a livello di indice.

Diamo un'occhiata 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'])

inserisci qui la descrizione dell'immagine

Questo DataFrame ha un livello per ciascuno degli indici di riga e colonna. Sia l'indice di riga che quello di colonna non hanno nome. Cambiamo il nome del livello dell'indice di riga in "nomi".

df.rename_axis('names')

inserisci qui la descrizione dell'immagine

Il rename_axismetodo ha anche la possibilità di cambiare i nomi a livello di colonna modificando il axisparametro:

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

inserisci qui la descrizione dell'immagine

Se si imposta l'indice con alcune delle colonne, il nome della colonna diventerà il nuovo nome del livello di indice. Aggiungiamo i livelli di indice al nostro DataFrame originale:

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

inserisci qui la descrizione dell'immagine

Notare come l'indice originale non ha nome. Possiamo ancora usare rename_axisma dobbiamo passare un elenco della stessa lunghezza del numero di livelli di indice.

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

inserisci qui la descrizione dell'immagine

È possibile utilizzare Noneper eliminare in modo efficace i nomi a livello di indice.


Le serie funzionano in modo simile ma con alcune differenze

Creiamo una serie con tre livelli di indice

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

Possiamo usare in rename_axismodo simile a come abbiamo fatto 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

Nota che c'è un pezzo extra di metadati sotto la serie chiamata Name. Quando si crea una serie da un DataFrame, questo attributo è impostato sul nome della colonna.

Possiamo passare un nome stringa al renamemetodo per cambiarlo

s.rename('FOOOOOD')

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

DataFrames non ha questo attributo e infatti genererà un'eccezione se usato in questo modo

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

Prima dei panda 0.21, avresti potuto usare rename_axisper rinominare i valori nell'indice e nelle colonne. È stato deprecato, quindi non farlo


1
Dovresti scambiare df1 = df.set_index(['state', 'color'], append=True)con df1.rename_axis(['names', None, 'Colors'])?
Salhin,

E se volessi rinominare "Nick" in "Nicolas"? Era quello che stavo cercando quando ho cercato su Google "Rinomina indice panda" e sono finito qui. EDIT: Oh aspetta, la risposta accettata lo spiega, all'inizio non era ovvio per me.
Ben Farmer,

Bene, questa è l'unica risposta che può essere utilizzata in incarichi concatenati!
IanS,

19

Per le pandasversioni più recenti

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

o

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

Quest'ultimo è necessario se un frame di dati deve conservare tutte le sue proprietà.


18

In Pandas versione 0.13 e successive i nomi dei livelli di indice sono immutabili (tipo FrozenList) e non possono più essere impostati direttamente. È innanzitutto necessario utilizzare Index.rename()per applicare i nuovi nomi a livello di indice all'indice e quindi utilizzare DataFrame.reindex()per applicare il nuovo indice a DataFrame. Esempi:

Per la versione di Pandas <0.13

df.index.names = ['Date']

Per la versione di Panda> = 0.13

df = df.reindex(df.index.rename(['Date']))

9
Non vero! Nella mia versione di Pandas (0.13.1) df.index.names = ['foo'] funziona bene!
Londra,

5
Grazie per aver notato che @LondonRob - `df.index.names = ['foo']` funziona anche per me con Panda 0.14. Apparentemente è stato rotto solo brevemente e incluso quando l'ho provato.
David Smith,

1
L'impostazione dei nomi per uno indexo columndirettamente sta cambiando entrambi per me (su Panda 0.19), ma non con questo metodo.
FooBar,

8

Puoi anche usare Index.set_namescome segue:

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

2
Questo può funzionare per 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])È possibile rinominare il Noneto measures?
ctrl-alt-delete

2

Se si desidera utilizzare lo stesso mapping per rinominare sia le colonne che l'indice, è possibile:

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)

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

È l'unico che fa il lavoro per me (Panda 0.22.0).
Senza inplace = True, il nome dell'indice non è impostato nel mio caso.


0

è possibile utilizzare indexe gli columnsattributi di pandas.DataFrame. NOTA: il numero di elementi dell'elenco deve corrispondere al numero di righe / colonne.

#       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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.