> Modules non standards > Pandas > Multiindex
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