Skip to article frontmatterSkip to article content
import pandas as pd

ceci est une version un peu plus évoluée que dans l’exercice précédent stack(): usage typique
sauf que cette fois-ci, chaque type (t1, t2, t3, ...) est décrit par 3 colonnes

df = pd.read_csv("data/stack-multicol.csv")
df
Loading...

et notre objectif est de le transformer en ceci

indexcitypostcodetypeattributevalue
0London90000t1nb1
0London90000t1price1000
0London90000t2nb2
0London90000t2price2000
0Paris75000t2nb2
0Paris75000t2price4000

notez bien que

# quelques variables utiles pour la suite

types = ['t1', 't2', 't3']
attributes = ['nb', 'price', 'junk']

on coupe en deux

comme dans le premier exercice, on commence par calculer les colonnes qui contiennent les données à retravailler

les colonnes de la partie droite

on calcule la liste [ "t1_nb", "t1_price", ...] à partir du produit cartésien des deux listes

# à vous
true_columns = ...
# et maintenant on extrait ces colonnes-là dans une dataframe
df2 = ...

la partie gauche

# il s'agit maintenant de prendre les autres données
# i.e. les colonnes qui ne sont pas dans df2

# à vous
df_left = ...
# pour vérification

df_left
Ellipsis
# pour vérification

df2
Ellipsis

on crée un MultiIndex

c’est le multi index qui va nous permettre de stacker correctement

# fabriquez un multi-index

multi_index = ...
# adoptez ce multi-index comme index des colonnes de df2

...
Ellipsis
# vérifiez visuellement que les colonnes sont indexées correctement


df2
Ellipsis

on nettoie (1): junk

rappelez-vous qu’on ne s’intéressait pas aux données junk
du coup il est temps de nettoyer la table de ces colonnes-là

# à vous pour le nettoyage
...

stack()

à ce stade tout est prêt quasiment pour actionner la magie de stack(), essayez et regardez ce que ça vous donne

# à vous

df3 = ...
# pour vérifier

df3
Ellipsis

on nettoie (2): les colonnes vides

ça n’était pas vraiment délibéré au départ
mais le cas est intéressant: aucune ville n’a de t3

# à vous de supprimer les colonnes sans intérêt
...

stack() à nouveau

maintenant qu’on s’est débarrassés de t3, on peut stacker à nouveau comme on avait fait dans stack-simple

et comme dans stack-simple on obtient une série car l’index des colonnes est simple

# à vous

s = ...

les labels

en première lecture, passez cette question, puis quand vous arriverez à la fin revenez-y pour affiner les labels dans le résultat final

# laissez vide en première lecture
s
Ellipsis

etc...

essentiellement maintenant, c’est la même logique que dans l’exercice stack(): usage typique, je vous laisse finir pour obtenir le résultat souhaité

# à vous

df_final = ...
df_final
Ellipsis

pas demandé

# ce n'était pas demandé, mais 
# si on veut remettre un index propre, on n'a qu'à faire

df_final.index = pd.RangeIndex(0, len(df_final))
df_final
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[22], line 4
      1 # ce n'était pas demandé, mais 
      2 # si on veut remettre un index propre, on n'a qu'à faire
----> 4 df_final.index = pd.RangeIndex(0, len(df_final))
      5 df_final

TypeError: object of type 'ellipsis' has no len()

à quoi ça sert ?

les usages pour ce type de traitement sont nombreux, par exemple

# sous cette forme, on peut s'intéresser à un type particulier

df_t1 = df_final.loc[df_final.type == 't1', :]
df_t1
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[23], line 3
      1 # sous cette forme, on peut s'intéresser à un type particulier
----> 3 df_t1 = df_final.loc[df_final.type == 't1', :]
      4 df_t1

AttributeError: 'ellipsis' object has no attribute 'loc'
# ou juste les nombres

df_t1_nb = df_t1[df_t1.attribute == 'nb']
df_t1_nb
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[24], line 3
      1 # ou juste les nombres
----> 3 df_t1_nb = df_t1[df_t1.attribute == 'nb']
      4 df_t1_nb

NameError: name 'df_t1' is not defined