Apprentissage du developpement avancé avec Python
Apprentissage du developpement avancé avec Python

Manipulation de données avec pandas et openpyxl

Bienvenue dans ce module avancé de développement Python ! Dans le monde de l'analyse et de la manipulation de données, Python est devenu un outil incontournable, en grande partie grâce à des bibliothèques puissantes telles que pandas et openpyxl. Ce cours, axé sur l'apprentissage du développement avancé avec Python, vous guidera à travers l'utilisation de ces deux outils essentiels pour interagir efficacement avec des données tabulaires et des fichiers Excel.

Introduction

Dans de nombreux domaines (finance, recherche, marketing, etc.), les données sont souvent stockées et échangées sous forme de fichiers tabulaires, notamment les fichiers .csv et les feuilles de calcul Excel (.xlsx). La capacité de lire, manipuler, analyser et écrire ces données de manière programmatique est une compétence fondamentale pour tout développeur ou analyste de données.

  • pandas est la bibliothèque de facto pour la manipulation et l'analyse de données en Python. Elle offre des structures de données rapides et flexibles, conçues pour rendre le travail avec des données "relationnelles" ou "étiquetées" à la fois facile et intuitif.
  • openpyxl est une bibliothèque Python dédiée à la lecture et à l'écriture de fichiers Excel au format .xlsx. Bien que pandas puisse lire et écrire des fichiers Excel, openpyxl offre un contrôle beaucoup plus fin sur la structure du fichier, les styles, les formules et d'autres fonctionnalités spécifiques à Excel.

Dans cette leçon, nous explorerons ces deux bibliothèques individuellement, puis nous verrons comment les combiner pour créer des solutions robustes de traitement de données.

1. Introduction à pandas : Le Couteau Suisse de la Manipulation de Données

pandas est une bibliothèque open-source qui fournit des structures de données haute performance et des outils d'analyse de données. Ses structures de données principales sont les Series (tableaux 1D étiquetés) et les DataFrames (tableaux 2D étiquetés, semblables à des feuilles de calcul ou des tables de bases de données).

1.1. Installation

Pour installer pandas, utilisez pip :

pip install pandas

1.2. Concepts Clés : Series et DataFrame

  • Series : Un objet Series est un tableau unidimensionnel capable de contenir n'importe quel type de données (entiers, chaînes, flottants, objets Python, etc.). Il possède un index (étiquettes d'axe) qui lui est associé, permettant une récupération rapide des données par étiquette.
  • DataFrame : Un DataFrame est une structure de données tabulaire à deux dimensions, avec des lignes et des colonnes étiquetées. C'est la structure la plus couramment utilisée pour représenter des données structurées. Pensez-y comme une feuille de calcul Excel ou une table SQL.

1.3. Création et Manipulation Basique de DataFrame

Un DataFrame peut être créé à partir de diverses sources : dictionnaires, listes de listes, tableaux NumPy, ou même directement à partir de fichiers (CSV, Excel, SQL, etc.).

Exemple de Code 1 : Création et manipulation basique de DataFrame

import pandas as pd

# 1. Création d'un DataFrame à partir d'un dictionnaire
data = {
    'Nom': ['Alice', 'Bob', 'Charlie', 'David'],
    'Âge': [25, 30, 35, 28],
    'Ville': ['Paris', 'Lyon', 'Marseille', 'Paris'],
    'Score': [85, 92, 78, 95]
}
df = pd.DataFrame(data)

print("--- DataFrame initial ---")
print(df)
print("\n")

# 2. Sélection de colonnes
print("--- Sélection de la colonne 'Nom' ---")
print(df['Nom'])
print("\n")

print("--- Sélection de plusieurs colonnes ('Nom', 'Score') ---")
print(df[['Nom', 'Score']])
print("\n")

# 3. Filtrage de lignes (par condition)
print("--- Personnes de plus de 30 ans ---")
df_adultes = df[df['Âge'] > 30]
print(df_adultes)
print("\n")

# 4. Ajout d'une nouvelle colonne
df['Status'] = ['Actif' if score > 80 else 'Inactif' for score in df['Score']]
print("--- DataFrame avec nouvelle colonne 'Status' ---")
print(df)
print("\n")

# 5. Calculs agrégés
print("--- Âge moyen :", df['Âge'].mean())
print("--- Score maximum :", df['Score'].max())
print("\n")

# 6. Groupement de données
print("--- Score moyen par ville ---")
score_moyen_par_ville = df.groupby('Ville')['Score'].mean()
print(score_moyen_par_ville)
print("\n")

# 7. Lecture et écriture de fichiers CSV (très courant avec pandas)
# Créons un fichier CSV temporaire
df.to_csv('donnees_personnes.csv', index=False)
print("DataFrame sauvegardé dans 'donnees_personnes.csv'")

# Lecture du fichier CSV
df_lu = pd.read_csv('donnees_personnes.csv')
print("\n--- DataFrame lu depuis 'donnees_personnes.csv' ---")
print(df_lu)

Explication du Code 1 :

  • Nous commençons par créer un DataFrame à partir d'un dictionnaire où les clés deviennent les noms de colonnes et les valeurs sont des listes de données.
  • La sélection de colonnes se fait avec la notation df['colonne'] pour une seule colonne (retourne une Series) ou df[['colonne1', 'colonne2']] pour plusieurs colonnes (retourne un autre DataFrame).
  • Le filtrage utilise une condition booléenne appliquée directement au DataFrame (df[df['Âge'] > 30]).
  • L'ajout d'une colonne est aussi simple que d'assigner une liste ou une Series à un nouveau nom de colonne.
  • Des fonctions agrégées comme mean() et max() sont disponibles directement sur les Series (colonnes).
  • La méthode groupby() permet d'effectuer des opérations sur des groupes de données (par exemple, calculer le score moyen pour chaque ville).
  • to_csv() et read_csv() sont des méthodes très utiles pour l'import/export de données depuis/vers des fichiers CSV, montrant la facilité d'intégration de pandas avec le système de fichiers. L'argument index=False dans to_csv() évite d'écrire l'index du DataFrame comme une colonne dans le fichier CSV.

2. Introduction à openpyxl : Maîtrise des Fichiers Excel .xlsx

openpyxl est la bibliothèque recommandée pour travailler avec les fichiers Excel .xlsx (Excel 2010 et plus). Elle vous permet de lire, écrire et manipuler les cellules, les feuilles de calcul, les styles, les images, les graphiques et plus encore, offrant un contrôle précis sur la structure du fichier Excel.

2.1. Installation

Pour installer openpyxl, utilisez pip :

pip install openpyxl

2.2. Concepts Clés : Workbook, Sheet, Cell

  • Workbook (Classeur) : Représente l'intégralité du fichier Excel. C'est l'objet de plus haut niveau.
  • Sheet (Feuille de calcul) : Un classeur contient une ou plusieurs feuilles de calcul. Vous accédez aux feuilles par leur nom ou par leur index.
  • Cell (Cellule) : L'unité de base d'une feuille de calcul. Chaque cellule est identifiée par sa coordonnée (par exemple, A1, B5).

2.3. Lecture de Données depuis Excel avec openpyxl

Pour lire un fichier Excel, vous chargez d'abord le classeur, puis vous sélectionnez la feuille désirée et enfin vous accédez aux cellules.

Exemple de Code 2 : Lecture de données depuis Excel

import openpyxl

# Création d'un fichier Excel pour l'exemple (si non existant)
try:
    workbook = openpyxl.load_workbook('ventes.xlsx')
except FileNotFoundError:
    workbook = openpyxl.Workbook()
    sheet = workbook.active
    sheet.title = "Données de Vente"
    sheet['A1'] = "Produit"
    sheet['B1'] = "Quantité"
    sheet['C1'] = "Prix Unitaire"
    sheet['A2'] = "Lait"
    sheet['B2'] = 10
    sheet['C2'] = 1.2
    sheet['A3'] = "Pain"
    sheet['B3'] = 5
    sheet['C3'] = 2.5
    sheet['A4'] = "Oeufs"
    sheet['B4'] = 12
    sheet['C4'] = 0.3
    workbook.save('ventes.xlsx')
    print("Fichier 'ventes.xlsx' créé pour l'exemple.")

# Charger un classeur existant
workbook = openpyxl.load_workbook('ventes.xlsx')

# Sélectionner la feuille active ou une feuille par son nom
sheet = workbook.active # ou workbook['Données de Vente']

print("--- Lecture de données depuis 'ventes.xlsx' ---")

# Accéder à une cellule spécifique
produit_cell = sheet['A2']
print(f"Cellule A2: {produit_cell.value}") # Affiche 'Lait'

# Itérer sur les lignes et les colonnes
print("\nDonnées du fichier Excel :")
for row in sheet.iter_rows(min_row=1, max_col=3, values_only=True):
    # values_only=True retourne directement les valeurs des cellules au lieu des objets Cell
    print(row)

# Accéder à des plages de cellules
# Par exemple, les données sans l'en-tête
print("\nDonnées tabulaires (sans en-tête) :")
for row in sheet.iter_rows(min_row=2, max_col=3, values_only=True):
    print(row)

Explication du Code 2 :

  • Le bloc try-except est utilisé pour créer le fichier ventes.xlsx si celui-ci n'existe pas, afin que l'exemple soit exécutable directement.
  • openpyxl.load_workbook('chemin/vers/fichier.xlsx') charge le fichier Excel en mémoire.
  • workbook.active accède à la feuille actuellement active. Vous pouvez aussi utiliser workbook['NomDeLaFeuille'].
  • Les cellules peuvent être accédées comme un dictionnaire avec leur coordonnée (ex: sheet['A1']). L'attribut .value contient la valeur de la cellule.
  • sheet.iter_rows() est une méthode puissante pour itérer sur les lignes. Vous pouvez spécifier min_row, max_row, min_col, max_col pour définir la plage. values_only=True est très pratique pour obtenir directement les valeurs.

2.4. Écriture de Données vers Excel avec openpyxl

Pour écrire dans un fichier Excel, vous créez un nouveau classeur ou en chargez un existant, puis vous définissez les valeurs des cellules et sauvegardez le classeur.

Exemple de Code 3 : Écriture de données vers Excel

import openpyxl

# Créer un nouveau classeur
workbook = openpyxl.Workbook()

# Obtenir la feuille active (par défaut, elle s'appelle "Sheet")
sheet = workbook.active
sheet.title = "Rapport Mensuel" # Renommer la feuille

# Écrire des données dans des cellules spécifiques
sheet['A1'] = "Rapport des Ventes - Octobre"
sheet['A3'] = "Produit"
sheet['B3'] = "Total Ventes (€)"

# Écrire des données ligne par ligne
ventes_data = [
    ["Ordinateur", 15000],
    ["Tablette", 8000],
    ["Smartphone", 22000],
    ["Accessoires", 3500]
]

# Ajouter plusieurs lignes à la fois
for row_data in ventes_data:
    sheet.append(row_data) # append ajoute une ligne après la dernière ligne non vide

# Mettre à jour une cellule existante
sheet['B7'] = "=SUM(B4:B6)" # Écrire une formule Excel

# Sauvegarder le classeur
workbook.save('rapport_ventes.xlsx')
print("Fichier 'rapport_ventes.xlsx' créé avec succès.")

# --- Modification d'un fichier existant ---
print("\n--- Modification d'un fichier existant ---")
# Charger le fichier que nous venons de créer
workbook_exist = openpyxl.load_workbook('rapport_ventes.xlsx')
sheet_exist = workbook_exist['Rapport Mensuel']

# Ajouter un titre pour le total
sheet_exist['A7'] = "Total Général"

# Sauvegarder les modifications
workbook_exist.save('rapport_ventes_modifie.xlsx')
print("Fichier 'rapport_ventes_modifie.xlsx' créé avec les modifications.")

Explication du Code 3 :

  • openpyxl.Workbook() crée un nouveau classeur vide.
  • sheet.title = "..." permet de renommer la feuille active.
  • Vous pouvez assigner des valeurs directement aux cellules en utilisant la notation de dictionnaire (sheet['A1'] = "Valeur").
  • La méthode sheet.append(liste_de_valeurs) est très utile pour ajouter une nouvelle ligne de données à la fin de la feuille.
  • openpyxl permet d'écrire des formules Excel directement dans les cellules, comme "=SUM(B4:B6)".
  • workbook.save('nom_du_fichier.xlsx') enregistre le classeur sur le disque.
  • Le second bloc montre comment charger un fichier existant, apporter des modifications et le sauvegarder (potentiellement sous un nouveau nom pour conserver l'original).

3. Synergie : pandas et openpyxl Ensemble

pandas et openpyxl sont extrêmement complémentaires. pandas excelle dans l'analyse et la manipulation de données tabulaires, tandis qu'openpyxl offre un contrôle fin sur la structure du fichier Excel lui-même, y compris les cellules non tabulaires, les formules, les styles, etc.

3.1. pandas et l'intégration Excel : read_excel et to_excel

pandas possède des fonctions intégrées pour lire et écrire des fichiers Excel, qui utilisent openpyxl (ou d'autres moteurs comme xlrd / xlwt) en arrière-plan.

  • pd.read_excel('chemin/vers/fichier.xlsx'): Lit les données d'une feuille Excel et les transforme en DataFrame. C'est l'outil de choix pour importer des données tabulaires standard.
  • df.to_excel('chemin/vers/fichier.xlsx'): Écrit un DataFrame dans une feuille Excel.

Ces fonctions sont parfaites pour les scénarios où l'intégralité ou une grande partie d'une feuille est une table de données.

import pandas as pd

# Création d'un DataFrame de démonstration
data_for_excel = {
    'Produit': ['Pomme', 'Banane', 'Orange'],
    'Quantité_Vendue': [150, 200, 100],
    'Revenu_Unitaire': [0.5, 0.7, 0.6]
}
df_excel = pd.DataFrame(data_for_excel)

# Écrire le DataFrame dans un nouveau fichier Excel
df_excel.to_excel('rapport_produits.xlsx', sheet_name='Statistiques', index=False)
print("DataFrame exporté vers 'rapport_produits.xlsx' (feuille 'Statistiques').")

# Lire un DataFrame depuis un fichier Excel
df_lu_excel = pd.read_excel('rapport_produits.xlsx', sheet_name='Statistiques')
print("\n--- DataFrame lu depuis 'rapport_produits.xlsx' ---")
print(df_lu_excel)

Explication : Ces fonctions sont le moyen le plus simple d'importer/exporter des DataFrames vers/depuis des fichiers Excel. Elles sont suffisantes pour la plupart des besoins de traitement de données tabulaires.

3.2. Quand utiliser openpyxl directement avec pandas ?

Vous utiliserez openpyxl directement quand :

  • Vous avez besoin de lire des données qui ne sont pas structurées comme une table simple (par exemple, des en-têtes complexes, des métadonnées dispersées sur la feuille).
  • Vous devez modifier un fichier Excel existant sans réécrire l'intégralité d'une feuille (par exemple, mettre à jour une seule cellule, ajouter un graphique, modifier le formatage).
  • Vous souhaitez générer des rapports Excel complexes avec des formules, des styles, des fusions de cellules, des images, etc., qui vont au-delà de la simple exportation de données brutes.

Exemple de Code 4 : Synergie openpyxl pour la lecture non tabulaire et pandas pour le traitement

Imaginez un rapport Excel où les métadonnées (titre, date) sont en haut, suivies d'une table de données.

import openpyxl
import pandas as pd

# --- Partie 1: Création d'un fichier Excel "complexe" pour la démo ---
# Ce code simule un fichier Excel avec des données non tabulaires en en-tête
# et une table de données plus bas.
try:
    wb = openpyxl.load_workbook('rapport_ventes_detaille.xlsx')
except FileNotFoundError:
    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = "Rapport Détaillé"
    
    ws['A1'] = "Rapport Annuel des Ventes Globales"
    ws['A3'] = "Date de génération:"
    ws['B3'] = "2023-10-27"
    
    ws['A5'] = "ID Transaction"
    ws['B5'] = "Client"
    ws['C5'] = "Montant"
    ws['D5'] = "Statut"
    
    transactions = [
        [101, "Alice", 120.50, "Terminée"],
        [102, "Bob", 250.00, "En cours"],
        [103, "Charlie", 75.25, "Terminée"],
        [104, "David", 300.00, "Annulée"],
        [105, "Eve", 180.00, "Terminée"]
    ]
    
    for row_data in transactions:
        ws.append(row_data) # Ajoute après la dernière ligne non vide (ici ligne 5)
    
    wb.save('rapport_ventes_detaille.xlsx')
    print("Fichier 'rapport_ventes_detaille.xlsx' créé pour l'exemple.")

# --- Partie 2: Lecture avec openpyxl et transformation en DataFrame ---
workbook = openpyxl.load_workbook('rapport_ventes_detaille.xlsx')
sheet = workbook['Rapport Détaillé']

# Extraire les métadonnées avec openpyxl
report_title = sheet['A1'].value
generation_date = sheet['B3'].value

print(f"Titre du rapport: {report_title}")
print(f"Date de génération: {generation_date}")

# Extraire les données tabulaires pour pandas
# Nous savons que les en-têtes sont à la ligne 5 et les données commencent à la ligne 6.
data_rows = []
for row in sheet.iter_rows(min_row=6, values_only=True): # Commencez après l'en-tête (ligne 5)
    # openpyxl peut retourner des lignes avec des valeurs None si elles sont vides
    if all(cell is None for cell in row): # Arrêter si la ligne est vide
        break
    data_rows.append(list(row)) # Convertir le tuple en liste

# Récupérer les en-têtes
headers = [cell.value for cell in sheet[5]] # Ligne 5 contient les en-têtes

# Créer le DataFrame
df_transactions = pd.DataFrame(data_rows, columns=headers)

print("\n--- DataFrame des transactions ---")
print(df_transactions)

# --- Partie 3: Traitement avec pandas ---
# Calculer le total des ventes pour les transactions "Terminée"
ventes_terminees = df_transactions[df_transactions['Statut'] == 'Terminée']['Montant'].sum()

print(f"\nTotal des ventes terminées: {ventes_terminees:.2f} €")

# --- Partie 4: Mise à jour du fichier Excel avec openpyxl (après traitement pandas) ---
# Chargeons à nouveau le même fichier (ou le classeur déjà chargé si c'était le cas)
workbook = openpyxl.load_workbook('rapport_ventes_detaille.xlsx')
sheet = workbook['Rapport Détaillé']

# Écrire le total des ventes terminées dans une nouvelle cellule du rapport
sheet['A10'] = "Total Ventes Terminées:"
sheet['B10'] = ventes_terminees

# Sauvegarder les modifications
workbook.save('rapport_ventes_detaille_final.xlsx')
print(f"\nLe total des ventes terminées a été ajouté à 'rapport_ventes_detaille_final.xlsx' en cellule B10.")

Explication du Code 4 :

  • Partie 1 (Création du fichier) : Nous utilisons openpyxl pour simuler la création d'un fichier Excel qui contient des informations non tabulaires (titre, date) en haut de la feuille, suivies d'une table de données. Cela représente un scénario courant de "rapport" où les données ne commencent pas nécessairement à A1.
  • Partie 2 (Lecture avec openpyxl et conversion pandas) :
    • Nous utilisons openpyxl pour accéder aux cellules spécifiques (A1, B3) pour extraire les métadonnées du rapport, ce que pd.read_excel() ne ferait pas facilement sans options complexes.
    • Nous utilisons sheet.iter_rows() avec min_row pour commencer l'extraction de données après la zone des métadonnées, garantissant que nous capturons uniquement les données tabulaires.
    • Les en-têtes sont récupérés spécifiquement de la ligne 5.
    • Enfin, les données extraites et les en-têtes sont utilisés pour construire un DataFrame pandas.
  • Partie 3 (Traitement avec pandas) : Une fois les données dans un DataFrame, toutes les puissantes fonctionnalités de pandas sont disponibles. Ici, nous filtrons les transactions terminées et calculons leur somme.
  • Partie 4 (Mise à jour avec openpyxl) : Le résultat du calcul (ventes_terminees) est ensuite écrit dans une cellule spécifique de l'Excel original à l'aide d'openpyxl. C'est un cas d'usage clé : pandas pour l'analyse, openpyxl pour la mise à jour ciblée d'un rapport existant. Nous sauvegardons le résultat dans un nouveau fichier pour ne pas écraser l'original, mais en pratique vous pourriez écraser le même fichier.

4. Bonnes Pratiques et Conseils

  • Gestion des erreurs : Toujours inclure des blocs try-except pour gérer les FileNotFoundError ou d'autres exceptions lors de l'ouverture/sauvegarde de fichiers.
  • Performance : Pour des fichiers Excel très volumineux (des centaines de milliers de lignes ou plus), openpyxl peut être lent si vous itérez cellule par cellule. pandas.read_excel() est souvent plus optimisé pour la lecture de grandes tables. Pour l'écriture, df.to_excel() est également très performant pour les DataFrames entiers.
  • Mémoire : Les fichiers Excel peuvent être gourmands en mémoire. openpyxl a un mode read_only (lors du chargement du classeur) et write_only (lors de la création du classeur) qui peuvent aider à réduire l'utilisation de la mémoire pour les très gros fichiers.
  • Choix de l'outil :
    • Utilisez pandas si votre tâche principale est de lire des données tabulaires, les manipuler (filtrer, agréger, joindre), les analyser statistiquement et les écrire comme des tables.
    • Utilisez openpyxl si vous avez besoin d'un contrôle fin sur la structure du fichier Excel (.xlsx), de modifier des cellules spécifiques, d'appliquer des styles, de gérer des formules, des images, des graphiques ou de travailler avec des données non tabulaires.
    • Combinez-les pour les tâches complexes : openpyxl pour extraire des données spécifiques ou modifier des mises en page existantes, pandas pour le traitement intensif des données, puis openpyxl pour insérer les résultats ou mettre à jour des parties du fichier.

Conclusion

La manipulation de données est au cœur de nombreuses applications Python avancées. pandas et openpyxl sont deux piliers fondamentaux pour interagir avec des données tabulaires et des fichiers Excel.

  • Vous avez appris que pandas est votre allié pour l'analyse, la transformation et la gestion de grandes quantités de données structurées grâce à ses DataFrames puissants et intuitifs.
  • Vous avez découvert qu'openpyxl vous donne un contrôle précis au niveau de la cellule, essentiel pour lire des structures complexes ou modifier des fichiers Excel existants avec des exigences de formatage spécifiques.
  • Plus important encore, vous avez vu comment ces deux bibliothèques peuvent être combinées pour créer des workflows de traitement de données sophistiqués, où openpyxl gère l'interaction brute avec le fichier Excel et pandas prend le relais pour l'intelligence des données.

Maîtriser ces outils vous ouvrira les portes à une multitude de projets de développement, de l'automatisation de rapports à l'intégration de systèmes, faisant de vous un expert en manipulation de données avec Python. Continuez à explorer leurs documentations respectives pour découvrir l'étendue complète de leurs capacités !