Mis a jour le 2025-04-14, 12:10

Multiindex

Ce sont des index à plusieurs niveaux, qu'on peut avoir aussi bien sur les lignes que sur les colonnes.
Attribution d'un multi-index à 2 niveaux, ici aux colonnes :
  • df = pandas.DataFrame({'A': [0, 1, 2], 'B': [3, 4, 5],
      'C': [6, 7, 8], 'D': [9, 10, 11]})
    df.columns = pandas.MultiIndex(levels = [['a', 'b'], ['A', 'B']],
      codes = [[0, 0, 1, 1], [0, 1, 0, 1]])
        
  • Ca donne :
    
       a     b    
       A  B  A   B
    0  0  3  6   9
    1  1  4  7  10
    2  2  5  8  11
        
  • dans levels, on donne les noms des labels (peu importe leur utilisation) avec une liste par niveau. Dans codes, on a aussi une liste par niveau et un élément par colonne qui indique l'index de l'élément de levels à attribuer. Peu importe si certains éléments de levels sont utilisés ou non.
  • on peut alors faire des group by : df.groupby(axis = 1, level = 0).sum(). Cela donne :
    
       a   b
    0  3  15
    1  5  17
    2  7  19
        
  • On peut définir aussi un multi-index à partir des colonnes existantes d'un dataframe :
    	df = pandas.DataFrame({'A': ['a', 'a', 'b', 'b'], 'B': ['c', 'd', 'c', 'd'], 'C': [1, 2, 3, 4]})
    	df.index = pandas.MultiIndex.from_frame(df.loc[:, ['A', 'B']])
          
    donne :
    
        A B C
    A B 
    a c a c 1
      d a d 2
    b c b c 3
      d b d 4
          
Pour remettre à plat un multi-index sur les lignes, faire simplement df.reset_index()
Pour remettre à un seul niveau un index hierarchique sur les colonnes : df.columns = ['_'.join(x) for x in df.columns.to_flat_index()]
Si les colonnes sont values = ['a', 'b', 'a', 'b', 'a', 'b'], on peut calculer les 2 listes de la façon suivante :
levels = list(set(values))
hash = {levels[i]:i for i in range(len(levels))}
codes = [hash[v] for v in values]
  
Avec un multi-index :
  • df.columns.levels : donne les niveaux FrozenList([['a', 'b'], ['A', 'B']])
  • df.columns.values : donne des tuples, un par colonne, chaque tuple donnant les valeurs de chaque niveau ('' si pas de valeur), ici array([('a', 'A'), ('a', 'B'), ('b', 'A'), ('b', 'B')], dtype=object)
  • pour avoir les valeurs du niveau le plus élevé : df.columns.levels[0].values : donne array(['a', 'b'], dtype=object)
  • on peut utiliser une valeur du niveau le plus élevé pour récupérer les données correspondantes : df['a'] (ou df.loc[:, 'a']) donne :
    
       A  B
    0  0  3
    1  1  4
    2  2  5
        
  • on peut aussi spécifier plusieurs niveaux : df.loc[:, ('a', 'B')]
  • mise à plat des niveaux : df.columns = ['/'.join(x) for x in df.columns.values]

Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert