Python pandas : flatten headers

Posté le : 15/12/2021

Partager

Dans ce court article, nous allons voir comment aplatir votre cadre de données pandas après l’opération d’agrégation.

 

Python pandas flatten headers

 

  • Pourquoi aplatir vos colonnes ?

 

Imaginez que vous travaillez avec votre dataframe comme vous le faites habituellement sur SQL Server : vous appliquez différentes opérations, comme joindre, agréger, sélectionner, etc. Cependant, après avoir exécuté une fonction d’agrégation sur votre dataframe pandas, vous avez des en-têtes de colonnes à plusieurs niveaux qui sont difficiles à manipuler. Après avoir examiné les questions de StackOverflow, j’ai finalement créé une fonction simple et flexible qui me permet de reconvertir mon ensemble de données agrégé dans le format initial. Donc, si cet extrait de code vous fait gagner quelques heures, je serai entièrement satisfait. Essayons!

 

  • Pourquoi cela se produit-il ?

 

Prenons cet exemple. Ici, nous avons une base de données que nous voulons agréger.


pe_odds[ [ ‘EVENT_ID’, ‘SELECTION_ID’, ‘ODDS’ ] ]

——————————————————————-

Out[67]:

EVENT_ID  SELECTION_ID   ODDS

0   100429300       5297529  18.001   100429300       5297529  20.002   100429300       5297529  21.003   100429300       5297529  22.004   100429300       5297529  23.005   100429300       5297529  24.006   100429300       5297529  25.00


Ensuite, lorsque vous regroupez par ID d’événement et ID de sélection, voici ce que vous avez, un cadre avec des colonnes multi-index :


pe_odds.groupby( [ ‘EVENT_ID’, ‘SELECTION_ID’ ] )[ ‘ODDS’ ].agg( [ np.min, np.max ] )

——————————————————————-

Out[68]:

amin   amax

EVENT_ID  SELECTION_ID

100428417 5490293        1.71   1.715881623        1.14   1.355922296        2.00   2.005956692        2.00   2.02100428419 603721         2.44   2.904387436        4.30   6.204398859        1.23   1.354574687        1.35   1.464881396       14.50  19.006032606        2.94   4.206065580        2.70   5.806065582        2.42   3.65100428421 5911426        2.22   2.52


Plutôt laid, on est d’accord.

 

 

« L’indexation hiérarchique / multi-niveaux est très intéressante car elle ouvre la porte à des analyses et manipulations de données assez sophistiquées, en particulier pour travailler avec des données dimensionnelles plus élevées. Essentiellement, cela vous permet de stocker et de manipuler des données avec un nombre arbitraire de dimensions dans des structures de données de dimension inférieure comme Series (1d) et dataframe (2d). »

 

C’est sans aucun doute passionnant. Mais ensuite, il devient relativement compliqué de manipuler votre dataframe, alors même que vous voulez peut être simplement le manipuler via de bonnes vieilles commandes SQL (puisque en général, le but de notre travail est de faire avancer les choses avec le moins d’effort possible).

Les suggestions sur StackOverflow n’étaient pas forcément pertinentes, nécessitaient trop de modifications du cadre de données initial ou n’étaient pas suffisamment flexibles. Si nous faisons un résumé de ce qui a été suggéré sur Internet, les solutions de contournement sont :

  1. Définissez les colonnes au niveau supérieur (à l’aide de DataFrame.get_level_values(0))
  2. Utilisez to_flat_index() qui a été publié à partir de pandas 0.24.0 (attention, il peut toujours y avoir des problèmes avec le nommage des colonnes)
  3. Convertir les colonnes en liste, puis les joindre toutes ensemble

 

Et dans mon cas, c’était encore pire car j’avais deux opérations d’agrégation, Mean et Std. J’ai donc créé une fonction simple, pour me débarrasser de ces colonnes multi-index bruyantes (encore une fois, elles sont géniales, c’est juste qu’elles étaient inutiles dans mon projet). Alors voilà:


def flatten_columns(columns):

return [first if second ==  » else second for first, second in

columns.values]


Et à l’intérieur du corps principal :


# e.g construct a correlation between columns

correlation_dataframe = generate_correlation_dataframe(unpivoted_dataframe, show_status)

# then aggregate using mean and standard deviation

aggregated_dataframe = correlation_dataframe.groupby([‘Year’, ‘Sequence’, ‘Variable’],as_index=False).agg({‘Correlation’:[‘mean’, ‘std’]})

# and flatten

aggregated_dataframe.columns = flatten_columns(aggregated_dataframe.columns)


 

Cela a fonctionné pour moi, mais si cela ne fonctionne pas pour vous, je vous serais très reconnaissant de partager votre expérience d’aplatissement des lignes multi-index des pandas ici.

 

Encore une fois, j’espère que vous aurez trouvé cet article utile.

 

Que la force soit avec vous !

 

Ecrit par Alibek Jakupov, Data scientist et Microsoft MVP Artifical Intelligence.

Contactez-nous Postuler Nos offres d'emploi