Python
Unstack de Pandas : Guide du débutant pour remodeler les données

Unstack de Pandas : Guide du débutant pour remodeler les données

MoeNagy Dev

Comprendre unstack de pandas

Explication de unstack de pandas

Qu'est-ce que unstack de pandas ?

unstack() est une fonction de pandas qui transforme un DataFrame d'un format long à un format large. Il prend un index de colonne à plusieurs niveaux et le "défasse", créant ainsi un nouveau DataFrame avec un ou plusieurs niveaux d'index devenant des colonnes.

Comment cela diffère-t-il de pivot et melt ?

La fonction unstack() est similaire à la fonction pivot(), mais elles ont des objectifs différents. pivot() est utilisée pour remodeler les données d'un format long à un format large, tandis que unstack() est utilisée pour remodeler les données d'un format large à un format long.

La fonction melt(), en revanche, est utilisée pour transformer les données d'un format large à un format long, ce qui est l'opposé de ce que fait unstack().

Quand utiliser unstack de pandas ?

Vous devez utiliser unstack() lorsque vous avez un DataFrame avec un index de colonne à plusieurs niveaux et que vous souhaitez le transformer en un format large, où les niveaux de l'index de colonne deviennent de nouvelles colonnes dans le DataFrame.

Préparation des données

Importation des bibliothèques nécessaires

import pandas as pd
import numpy as np

Création d'un DataFrame d'exemple

# Créer un DataFrame d'exemple
data = {
    ('Magasin A', 'Ventes'): [100, 120, 80, 90, 110],
    ('Magasin A', 'Profit'): [20, 25, 15, 18, 22],
    ('Magasin B', 'Ventes'): [150, 180, 120, 160, 200],
    ('Magasin B', 'Profit'): [30, 35, 25, 32, 40]
}
 
df = pd.DataFrame(data)

Exploration de la structure du DataFrame

print(df)
           (Magasin A, Ventes)  (Magasin A, Profit)  (Magasin B, Ventes)  (Magasin B, Profit)
0                      100                 20               150                 30
1                      120                 25               180                 35
2                       80                 15               120                 25
3                       90                 18               160                 32
4                      110                 22               200                 40

Comme vous pouvez le voir, le DataFrame a un index de colonnes à plusieurs niveaux, le premier niveau représentant le magasin et le deuxième niveau représentant la métrique (Ventes ou Profit).

Fondamentaux du unstack de pandas

Défaisage d'un index à un seul niveau

Pour défaires un index à un seul niveau, vous pouvez utiliser la fonction unstack() sans aucun argument :

df_unstacked = df.unstack()
print(df_unstacked)
                 Ventes        Profit
                 Magasin A   Magasin B   Magasin A   Magasin B
0                    100         150         20         30
1                    120         180         25         35
2                    80          120         15         25
3                    90          160         18         32
4                    110         200         22         40

Le DataFrame obtenu a les noms des magasins comme index de colonnes et les noms de colonnes d'origine (Ventes et Profit) sont devenus l'index des lignes.

Défaisage d'un index à plusieurs niveaux

Si le DataFrame a un index de colonnes à plusieurs niveaux, vous pouvez spécifier le niveau à défaires :

df_unstacked = df.unstack(level=0)
print(df_unstacked)
                  (Ventes, Magasin A)  (Ventes, Magasin B)  (Profit, Magasin A)  (Profit, Magasin B)
0                             100               150                 20                 30
1                             120               180                 25                 35
2                              80               120                 15                 25
3                              90               160                 18                 32
4                             110               200                 22                 40

Dans ce cas, les noms des magasins sont devenus l'index des colonnes et les noms de colonnes d'origine (Ventes et Profit) font maintenant partie de l'index de colonnes à plusieurs niveaux.

Comprendre la structure du DataFrame obtenu

Le DataFrame défait a un index de colonnes à plusieurs niveaux, où le premier niveau représente les noms de colonnes d'origine et le deuxième niveau représente les valeurs qui étaient précédemment dans l'index de colonnes.

Cette structure peut être utile pour certains types d'analyses de données et de visualisation, car elle vous permet d'accéder facilement aux données et de les manipuler de différentes manières.

Gestion des données manquantes dans unstack de pandas

Gérer les valeurs NaN

Si des valeurs manquantes existent dans le DataFrame d'origine, la fonction unstack() introduira des valeurs NaN dans le DataFrame obtenu :

# Ajouter des valeurs manquantes dans le DataFrame d'exemple
data = {
    ('Magasin A', 'Ventes'): [100, 120, 80, np.nan, 110],
    ('Magasin A', 'Profit'): [20, 25, 15, 18, 22],
    ('Magasin B', 'Ventes'): [150, 180, 120, 160, 200],
    ('Magasin B', 'Profit'): [30, 35, 25, 32, np.nan]
}
 
df = pd.DataFrame(data)
df_unstacked = df.unstack()
print(df_unstacked)
                 Ventes        Profit
                 Magasin A   Magasin B   Magasin A   Magasin B
0                    100         150         20         30.0
1                    120         180         25         35.0
2                    80          120         15         25.0
3                    NaN         160         18         32.0
4                    110         200         22          NaN

Vous pouvez voir que les valeurs manquantes dans le DataFrame d'origine ont été reportées dans le DataFrame défait.

Remplir les valeurs manquantes

Pour gérer les valeurs manquantes, vous pouvez utiliser la méthode fillna() pour les remplacer par une valeur spécifique :

df_unstacked = df.unstack().fillna(0)
print(df_unstacked)
                 Ventes        Profit
                 Magasin A   Magasin B   Magasin A   Magasin B
S'il vous plaît fournissez la traduction en français pour ce fichier Markdown. S'il y a des métadonnées, assurez-vous de traduire le paramètre de langue en fr correspondant également. Pour le code, ne traduisez pas le code, traduisez uniquement les commentaires. Ne traduisez pas le contenu de l'exemple. Voici le fichier:

```python
0 100 150 20 30
1 120 180 25 35
2 80 120 15 25
3 0 160 18 32
4 110 200 22 0

Dans cet exemple, nous remplissons les valeurs manquantes avec 0.

Spécification de la valeur de remplissage

Vous pouvez également spécifier une valeur de remplissage différente, telle que la moyenne ou la médiane de la colonne :

# Remplir les valeurs manquantes avec la moyenne de la colonne
df_unstacked = df.unstack().fillna(df.mean())
print(df_unstacked)
             Ventes       Profit
             Magasin A Magasin B Magasin A Magasin B
0                100       150        20    32.5
1                120       180        25    32.5
2                 80       120        15    32.5
3               95.0       160        18    32.5
4                110       200        22    22.0

Dans cet exemple, nous remplissons les valeurs manquantes avec la moyenne des colonnes respectives.

Techniques avancées avec unstack de pandas

Désempiler avec des niveaux spécifiés

Vous pouvez également désassembler des niveaux spécifiques de l'index de colonne, au lieu de désassembler tous les niveaux :

# Désassemblez le deuxième niveau de l'index de colonne
df_unstacked = df.unstack(level=1)
print(df_unstacked)
               Ventes  Profit
Magasin A  0      100      20
           1      120      25
           2       80      15
           3      NaN      18
           4      110      22
Magasin B  0      150      30
           1      180      35
           2      120      25
           3      160      32
           4      200      NaN

Dans ce cas, les noms des magasins sont devenus l'index des lignes, et les noms de colonnes d'origine (Ventes et Profit) sont devenus l'index des colonnes.

Combinaison de désassemblage avec d'autres opérations pandas

Vous pouvez combiner la fonction unstack() avec d'autres opérations pandas, telles que reset_index() ou rename(), pour manipuler davantage les données :

# Désassembler et réinitialiser l'index
df_unstacked = df.unstack().reset_index()
print(df_unstacked)
  level_0 level_1   0         1
0  Magasin A  Ventes  100       20
1  Magasin A  Ventes  120       25
2  Magasin A  Ventes   80       15
3  Magasin A  Ventes  NaN       18
4  Magasin A  Ventes  110       22
5  Magasin B  Ventes  150       30
6  Magasin B  Ventes  180       35
7  Magasin B  Ventes  120       25
8  Magasin B  Ventes  160       32
9  Magasin B  Ventes  200       NaN

Dans cet exemple, nous avons désassemblé le DataFrame puis réinitialisé l'index, ce qui crée un nouveau DataFrame avec les valeurs désassemblées dans une seule colonne.

Réinitialisation de l'index après désassemblage

Si vous voulez réinitialiser l'index après désassemblage, vous pouvez utiliser la méthode reset_index() :

# Désassembler et réinitialiser l'index
df_unstacked = df.unstack().reset_index()
print(df_unstacked)
  level_0 level_1   0         1
0  Magasin A  Ventes  100       20
1  Magasin A  Ventes  120       25
2  Magasin A  Ventes   80       15
3  Magasin A  Ventes  NaN       18
4  Magasin A  Ventes  110       22
5  Magasin B  Ventes  150       30
6  Magasin B  Ventes  180       35
7  Magasin B  Ventes  120       25
8  Magasin B  Ventes  160       32
9  Magasin B  Ventes  200       NaN

Cela crée un nouveau DataFrame avec les valeurs désassemblées dans une seule colonne, et les niveaux d'index d'origine sont désormais des colonnes dans le DataFrame.

Visualisation des données désassemblées

Création de heatmaps

Une façon de visualiser des données désassemblées consiste à créer un heatmap en utilisant la bibliothèque seaborn :

import seaborn as sns
import matplotlib.pyplot as plt
 
# Désassembler le DataFrame
df_unstacked = df.unstack()
 
# Créer un heatmap
plt.figure(figsize=(8, 6))
sns.heatmap(df_unstacked, annot=True, cmap="YlOrRd")
plt.title("Ventes et Profit par Magasin")
plt.show()

Cela créera un heatmap qui visualise les données de ventes et de profit pour chaque magasin.

Génération de tables croisées dynamiques

Vous pouvez également utiliser la fonction pivot_table() pour créer une table croisée dynamique à partir des données désassemblées :

# Créer une table croisée dynamique
table_croisee = df.pivot_table(index=['Magasin'], columns=['Mesure'], values=['Valeur'])
print(table_croisee)
              Valeur
Mesure    Profit  Ventes
Magasin A      20     100
            25     120
            15      80
            18      NaN
            22     110
Magasin B      30     150
            35     180
            25     120
            32     160
            NaN    200

Cette table croisée dynamique a les noms des magasins comme index de ligne et les noms des mesures comme index de colonne, avec les valeurs correspondantes dans les cellules.

Tracé des données désassemblées

Vous pouvez également tracer les données désassemblées directement, comme créer un graphique à barres ou un graphique linéaire :

# Tracer les données désassemblées
df_unstacked.plot(kind="bar", figsize=(10, 6))
plt.title("Ventes et Profit par Magasin")
plt.xlabel("Magasin")
plt.ylabel("Valeur")
plt.show()

Cela créera un graphique à barres qui montre les valeurs de ventes et de profit pour chaque magasin.

Applications pratiques de unstack de pandas

Analyse des données de ventes

Le désassemblage peut être utile pour analyser les données de ventes, en particulier lorsque vous avez un index de colonne à plusieurs niveaux. Vous pouvez utiliser les données désassemblées pour créer des tables croisées dynamiques, des heatmaps ou d'autres visualisations afin de mieux comprendre les tendances de vente et les performances dans différents magasins, produits ou périodes.

Réorganisation des données de séries temporelles

unstack() peut également être utile pour réorganiser les données de séries temporelles, lorsque vous avez un index à plusieurs niveaux avec le temps et une autre dimension (par exemple, la localisation, le produit). En désassemblant les données, vous pouvez créer un DataFrame au format large qui est plus facile à travailler pour certains types d'analyses et de visualisations.

Traitement des données d'enquête

Dans le cas de données d'enquête, où vous avez des réponses à différentes questions pour chaque participant, unstack() peut être utilisé pour transformer les données d'un format long en un format large, ce qui facilite l'analyse des relations entre différentes questions d'enquête.

Dépannage et meilleures pratiques

Problèmes courants et messages d'erreur

Un problème courant avec unstack() est qu'il peut introduire des valeurs NaN s'il y a

Fonctions

Les fonctions sont des blocs de code réutilisables qui effectuent une tâche spécifique. Elles peuvent prendre des paramètres d'entrée, effectuer des opérations et renvoyer une valeur. Les fonctions aident à organiser et à modulariser votre code, le rendant plus lisible et plus facile à maintenir.

Voici un exemple d'une fonction simple qui calcule l'aire d'un cercle :

def calculate_circle_area(radius):
    """
    Calcule l'aire d'un cercle.
 
    Args:
        radius (float): Le rayon du cercle.
 
    Returns:
        float: L'aire du cercle.
    """
    pi = 3.14159
    area = pi * (radius ** 2)
    return area
 
# Exemple d'utilisation
circle_radius = 5.0
circle_area = calculate_circle_area(circle_radius)
print(f"L'aire d'un cercle de rayon {circle_radius} est de {circle_area:.2f} unités carrées.")

Dans cet exemple, la fonction calculate_circle_area prend un paramètre radius, calcule l'aire en utilisant la formule pi * (radius ** 2), et renvoie le résultat. La fonction inclut également une docstring qui donne une brève description de la fonction, de son paramètre d'entrée et de sa valeur de retour.

Modules et Packages

La conception modulaire de Python vous permet d'organiser votre code en composants réutilisables appelés modules. Les modules sont des fichiers Python qui contiennent des définitions de variables, de fonctions et de classes. En important des modules, vous pouvez accéder et utiliser le code qu'ils fournissent.

Voici un exemple de création et d'utilisation d'un module personnalisé :

# my_module.py
def greet(name):
    print(f"Bonjour, {name} !")
 
# main.py
import my_module
 
my_module.greet("Alice")

Dans cet exemple, nous créons un module appelé my_module.py qui contient une fonction greet. Dans le fichier main.py, nous importons le my_module et appelons la fonction greet.

Les packages sont des collections de modules liés. Ils aident à organiser votre code et fournissent un moyen de regrouper et de distribuer votre code Python. Voici un exemple de structure de package simple :

my_package/
    __init__.py
    module1.py
    module2.py
    subpackage/
        __init__.py
        module3.py

Dans cet exemple, my_package est un package qui contient deux modules (module1.py et module2.py) et un sous-package (subpackage). Les fichiers __init__.py du package et du sous-package sont utilisés pour définir la structure et le comportement du package.

Programmation orientée objet (POO)

La programmation orientée objet (POO) est un paradigme de programmation qui se concentre sur la création d'objets contenant à la fois des données (attributs) et des fonctions (méthodes) pour représenter et manipuler ces données. La POO fournit des concepts tels que les classes, l'héritage et la polymorphie, qui aident à créer un code plus organisé et réutilisable.

Voici un exemple d'une classe simple en Python :

class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed
 
    def bark(self):
        print("Woof!")
 
# Exemple d'utilisation
my_dog = Dog("Buddy", "Labrador")
print(my_dog.name)  # Sortie : Buddy
print(my_dog.breed)  # Sortie : Labrador
my_dog.bark()  # Sortie : Woof!

Dans cet exemple, nous définissons une classe Dog avec une méthode __init__ qui initialise les attributs name et breed. La classe a également une méthode bark qui affiche "Woof!". Nous créons ensuite une instance de la classe Dog et accédons à ses attributs et méthodes.

La POO fournit également des concepts tels que l'héritage, où une classe enfant peut hériter des attributs et des méthodes d'une classe parente. Voici un exemple :

class GuideDog(Dog):
    def __init__(self, name, breed, can_guide):
        super().__init__(name, breed)
        self.can_guide = can_guide
 
    def guide(self):
        print("Je peux guider mon propriétaire.")
 
# Exemple d'utilisation
my_guide_dog = GuideDog("Buddy", "Labrador", True)
print(my_guide_dog.name)  # Sortie : Buddy
print(my_guide_dog.breed)  # Sortie : Labrador
print(my_guide_dog.can_guide)  # Sortie : True
my_guide_dog.bark()  # Sortie : Woof!
my_guide_dog.guide()  # Sortie : Je peux guider mon propriétaire.

Dans cet exemple, la classe GuideDog hérite de la classe Dog et ajoute un nouvel attribut can_guide et une nouvelle méthode guide. La méthode __init__ de la classe GuideDog appelle la méthode __init__ de la classe parente Dog en utilisant super().__init__ pour initialiser les attributs name et breed.

Exceptions et gestion des erreurs

Les exceptions sont des événements qui se produisent lors de l'exécution d'un programme et perturbent le flux normal des instructions du programme. Python dispose d'un mécanisme de gestion des exceptions intégré qui vous permet d'anticiper et de gérer ces exceptions.

Voici un exemple de gestion d'une exception ZeroDivisionError :

def divide(a, b):
    try:
        result = a / b
        return result
    except ZeroDivisionError:
        print("Erreur : division par zéro.")
        return None
 
# Exemple d'utilisation
print(divide(10, 2))  # Sortie : 5.0
print(divide(10, 0))  # Sortie : Erreur : division par zéro.

Dans cet exemple, la fonction divide tente de diviser a par b dans le bloc try. Si un ZeroDivisionError se produit, le code du bloc except est exécuté et un message est affiché. La fonction renvoie ensuite None pour indiquer que l'opération de division n'a pas réussi.

Vous pouvez également utiliser le bloc finally pour exécuter du code indépendamment de l'apparition ou non d'une exception. Cela est utile pour nettoyer des ressources, telles que la fermetur En comprenant et en appliquant ces techniques, vous serez bien parti pour devenir un programmeur Python compétent. N'oubliez pas de pratiquer régulièrement, d'expérimenter avec différents exemples de code et d'explorer le vaste écosystème des bibliothèques et des frameworks Python pour étendre vos connaissances et vos compétences.

Bon codage !

MoeNagy Dev