Analyse de Données avec Python

Classe B3 ASO 2025-2026

Module 4

Consolidation et Maîtrise de Pandas

Allez au-delà des bases en apprenant les techniques avancées pour répondre à des questions complexes, combiner des sources de données et nettoyer des données imparfaites.

4.1. Agrégation de Données avec groupby()

Pour répondre à des questions comme "Quel est le salaire moyen par département ?", on utilise la méthode groupby(). Elle suit une logique en 3 étapes : Split-Apply-Combine (Diviser-Appliquer-Combiner).

  1. Split : Le DataFrame est divisé en sous-groupes basés sur les valeurs d'une colonne.
  2. Apply : Une fonction (comme .mean(), .sum(), .count()) est appliquée à chaque sous-groupe.
  3. Combine : Les résultats sont rassemblés dans un nouveau DataFrame.
import pandas as pd data = { 'Nom': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank'], 'Département': ['IT', 'RH', 'IT', 'RH', 'IT', 'Marketing'], 'Salaire': [75000, 55000, 82000, 60000, 90000, 68000] } df = pd.DataFrame(data) # Calculons le salaire moyen par département salaire_moyen_par_dept = df.groupby('Département')['Salaire'].mean() print("Salaire moyen par département:\n", salaire_moyen_par_dept) # Comptons le nombre d'employés par département effectifs = df.groupby('Département').size() print("\nEffectifs par département:\n", effectifs)

4.2. Combiner des Données : merge et concat

Les données réelles sont rarement dans un seul fichier. Savoir les combiner est une compétence essentielle.

pd.merge() : La Jointure Intelligente

Utilisez merge() lorsque vous souhaitez combiner des DataFrames qui ont une colonne en commun (une "clé"). C'est l'équivalent des JOIN en SQL.

# DataFrame 1: Les employés employes = pd.DataFrame({ 'employee_id': [1, 2, 3, 4], 'nom': ['Alice', 'Bob', 'Charlie', 'David'], 'dept_id': [101, 102, 101, 103] }) # DataFrame 2: Les départements departements = pd.DataFrame({ 'dept_id': [101, 102, 103], 'dept_nom': ['IT', 'RH', 'Marketing'] }) # Fusionnons les deux sur la clé 'dept_id' df_complet = pd.merge(employes, departements, on='dept_id') print(df_complet)

pd.concat() : L'Empilement Brut

Utilisez concat() lorsque vous voulez empiler des DataFrames les uns sur les autres (concaténation de lignes). Les colonnes doivent être similaires.

ventes_jan = pd.DataFrame({'produit': ['A', 'B'], 'quantite': [100, 150]}) ventes_fev = pd.DataFrame({'produit': ['A', 'C'], 'quantite': [120, 50]}) # Empilons les deux DataFrames ventes_totales = pd.concat([ventes_jan, ventes_fev], ignore_index=True) print(ventes_totales)

4.3. Nettoyage de Données Avancé

Les données du monde réel sont "sales". Elles contiennent des doublons, des erreurs de frappe, des formats incohérents...

Gestion des Doublons

data_doublons = {'col1': ['A', 'B', 'A'], 'col2': [1, 2, 1]} df_doublons = pd.DataFrame(data_doublons) print("Avec doublons:\n", df_doublons) # Supprimer les lignes dupliquées df_sans_doublons = df_doublons.drop_duplicates(ignore_index=True) print("\nSans doublons:\n", df_sans_doublons)

Travailler avec du Texte (.str)

L'accesseur .str donne accès à toutes les méthodes de chaînes de caractères de Python, mais appliquées à une Series entière.

df_texte = pd.DataFrame({'ville': [' Paris', 'Londres ', ' new york ']}) # Standardiser les noms de ville df_texte['ville_propre'] = df_texte['ville'].str.strip().str.capitalize() print(df_texte)

Gérer les Dates et Heures (.dt)

Les dates sont souvent lues comme du texte. pd.to_datetime les convertit, et l'accesseur .dt permet d'en extraire des informations.

df_dates = pd.DataFrame({'date_str': ['2025-01-15', '2025-02-28']}) # 1. Convertir la colonne en format datetime df_dates['date'] = pd.to_datetime(df_dates['date_str']) # 2. Extraire des informations avec .dt df_dates['annee'] = df_dates['date'].dt.year df_dates['nom_jour'] = df_dates['date'].dt.day_name() print(df_dates)

Exercices Pratiques

Exercice 1 : Agrégation Multiple avec `groupby()`

En utilisant le DataFrame des employés de la section 4.1, calculez pour chaque département non seulement le salaire moyen, mais aussi le salaire maximum et le nombre total d'employés. Affichez le résultat dans un seul DataFrame.

Voir la solution
import pandas as pd data = { 'Nom': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank'], 'Département': ['IT', 'RH', 'IT', 'RH', 'IT', 'Marketing'], 'Salaire': [75000, 55000, 82000, 60000, 90000, 68000] } df = pd.DataFrame(data) # On utilise .agg() pour appliquer plusieurs fonctions d'agrégation stats_par_dept = df.groupby('Département')['Salaire'].agg(['mean', 'max', 'count']) # On renomme les colonnes pour plus de clarté stats_par_dept.columns = ['Salaire Moyen', 'Salaire Max', 'Nombre Employés'] print(stats_par_dept)

Exercice 2 : Fusionner des Données Clients et Commandes

Vous avez deux DataFrames : un avec des informations sur les clients, et un autre avec leurs commandes. Fusionnez ces deux tables pour obtenir un DataFrame qui contient le nom du client à côté de chaque commande.

clients = pd.DataFrame({ 'client_id': [1, 2, 3], 'nom': ['Alice', 'Bob', 'Charlie'] }) commandes = pd.DataFrame({ 'commande_id': [101, 102, 103, 104], 'client_id': [2, 1, 2, 3], 'montant': [150, 200, 50, 300] })
Voir la solution
import pandas as pd clients = pd.DataFrame({ 'client_id': [1, 2, 3], 'nom': ['Alice', 'Bob', 'Charlie'] }) commandes = pd.DataFrame({ 'commande_id': [101, 102, 103, 104], 'client_id': [2, 1, 2, 3], 'montant': [150, 200, 50, 300] }) # On fusionne les deux DataFrames sur la colonne commune 'client_id' donnees_fusionnees = pd.merge(commandes, clients, on='client_id') print(donnees_fusionnees)

Exercice 3 : Nettoyage de Données Textuelles

Vous recevez un DataFrame avec une colonne 'email' qui contient des données mal formatées (espaces inutiles, casse incohérente). Nettoyez cette colonne en retirant les espaces au début et à la fin, et en mettant tout en minuscules.

data_emails = {'email': [' Alice@Example.com ', 'BOB@EMAIL.COM', ' charlie@domain.org']} df_emails = pd.DataFrame(data_emails)
Voir la solution
import pandas as pd data_emails = {'email': [' Alice@Example.com ', 'BOB@EMAIL.COM', ' charlie@domain.org']} df_emails = pd.DataFrame(data_emails) # On enchaîne les méthodes de l'accesseur .str df_emails['email_propre'] = df_emails['email'].str.strip().str.lower() print(df_emails)