web-dev-qa-db-fra.com

Renommer Pandas Index de DataFrame

J'ai un fichier csv sans en-tête, avec un index DateTime. Je souhaite renommer l'index et le nom de la colonne, mais avec df.rename (), seul le nom de la colonne est renommé. Punaise? Je suis sur la version 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
109
Mattijn

La méthode rename utilise un dictionnaire pour l'index qui s'applique à l'index values.
Vous souhaitez renommer le nom du niveau d'indexation:

df.index.names = ['Date']

n bon moyen de penser à cela est que les colonnes et l'index sont du même type d'objet (Index ou MultiIndex), et que vous pouvez échanger les deux via transpose.

Ceci est un peu déroutant car les noms d'index ont une signification similaire à celle des colonnes, voici donc quelques exemples supplémentaires:

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

Vous pouvez voir le renommage sur l'index, ce qui peut changer le valeur 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

En renommant les noms de niveau:

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

Remarque: cet attribut est simplement une liste et vous pouvez renommer celle-ci en tant que compréhension/mappage de liste.

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

La réponse actuellement sélectionnée ne mentionne pas la méthode _rename_axis_ qui peut être utilisée pour renommer les niveaux d'index et de colonne.


Les pandas ont une certaine bizarrerie lorsqu'il s'agit de renommer les niveaux de l'index. Une nouvelle méthode DataFrame rename_axis est également disponible pour modifier les noms de niveau d'index.

Jetons un coup d'oeil à 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'])
_

enter image description here

Ce DataFrame a un niveau pour chacun des index de lignes et de colonnes. L'index des lignes et des colonnes n'ont pas de nom. Modifions le nom du niveau d'index de ligne en 'noms'.

_df.rename_axis('names')
_

enter image description here

La méthode _rename_axis_ permet également de modifier les noms de niveau de colonne en modifiant le paramètre axis:

_df.rename_axis('names').rename_axis('attributes', axis='columns')
_

enter image description here

Si vous définissez l'index avec certaines des colonnes, le nom de la colonne deviendra le nouveau nom du niveau de l'index. Ajoutons aux niveaux d'indexation notre DataFrame d'origine:

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

enter image description here

Notez que l'index d'origine n'a pas de nom. Nous pouvons toujours utiliser _rename_axis_ mais nous devons lui transmettre une liste de la même longueur que le nombre de niveaux d’index.

_df1.rename_axis(['names', None, 'Colors'])
_

enter image description here

Vous pouvez utiliser None pour supprimer efficacement les noms de niveau d'index.


Les séries fonctionnent de manière similaire mais avec quelques différences

Créons une série avec trois niveaux d'index

_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
_

Nous pouvons utiliser _rename_axis_ de la même façon qu'avec 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
_

Notez qu'il existe une métadonnée supplémentaire en dessous de la série appelée Name. Lors de la création d'une série à partir d'un DataFrame, cet attribut est défini sur le nom de la colonne.

Nous pouvons passer un nom de chaîne à la méthode rename pour le changer

_s.rename('FOOOOOD')

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

Les DataFrames n'ont pas cet attribut et infact lève une exception si utilisé comme ceci

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

Avant pandas 0.21, vous auriez pu utiliser _rename_axis_ pour renommer les valeurs de l'index et des colonnes. Il est déconseillé, alors ne le faites pas

41
Ted Petrou

Dans Pandas version 0.13 et ultérieure, les noms de niveau d'index sont immuables (type FrozenList) et ne peuvent plus être définis directement. Vous devez d’abord utiliser Index.rename() pour appliquer les nouveaux noms de niveau d’index à l’index, puis DataFrame.reindex() pour appliquer le nouvel index au DataFrame. Exemples:

Pour Pandas version <0.1

df.index.names = ['Date']

Pour Pandas version> = 0.1

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

Pour les nouvelles versions pandas

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

ou

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

Ce dernier est requis si un bloc de données doit conserver toutes ses propriétés.

11
Serge Stroobandt

Vous pouvez également utiliser Index.set_names comme suit:

_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
_
8
LondonRob

Si vous souhaitez utiliser le même mappage pour renommer les colonnes et l'index, vous pouvez procéder comme suit:

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

Est-ce le seul qui fait le travail pour moi (pandas 0.22.0).
Sans le inplace = True, le nom de l'index n'est pas défini dans mon cas.

0
Jan H.