import pandas as pdceci 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")
dfet notre objectif est de le transformer en ceci
| index | city | postcode | type | attribute | value |
|---|---|---|---|---|---|
| 0 | London | 90000 | t1 | nb | 1 |
| 0 | London | 90000 | t1 | price | 1000 |
| 0 | London | 90000 | t2 | nb | 2 |
| 0 | London | 90000 | t2 | price | 2000 |
| 0 | Paris | 75000 | t2 | nb | 2 |
| 0 | Paris | 75000 | t2 | price | 4000 |
notez bien que
on a enlevé tout ce qui concernait les nb==0
on ne se donne pas de spécification précise sur l’index, d’où les 0 mais ça peut être ce qu’on veut
# 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
indice
quelque chose comme
for typ in types:
for attribute in attributes:
columns.append(f"{typ}_{attribute}")# à 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_leftEllipsis# pour vérification
df2Ellipsison crée un MultiIndex¶
c’est le multi index qui va nous permettre de stacker correctement
indice
voyez pd.MultiIndex.from_product()
# 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
df2Ellipsison 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à
note - on aurait pu le faire plus tôt
ceux qui suivent vont trouver une façon de faire qui implique de remonter dans le temps
(je veux dire de traiter ce point plus tôt dans le notebook)
c’est vrai qu’on aurait pu faire comme ça, mais essayez tout de même de trouver une façon de le faire maintenant
# à 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
df2Ellipsis# pour vérifier
df3Ellipsison 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 lecturesEllipsisetc...¶
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é
indice
voir reset_index() et join()
# à vous
df_final = ...df_finalEllipsispas 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