Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Une petite chaîne de traitement

Après cette leçon: Je peux écrire une petite chaîne qui nettoie, relie et fait un rapport, et qui s’arrête quand un contrôle échoue.

Leçon de 60 min6 commandesLab JupyterLab de science des données : pandas, Matplotlib et scikit-learn dans le navigateur

Le même nettoyage, chaque lundi

Le patron envoie un nouvel export chaque lundi. Il a les mêmes défauts que la semaine passée : des répétitions, des mots là où il faut des nombres, des écritures bizarres.

Vous pourriez le nettoyer à la main dans un carnet à chaque fois. Ou écrire les étapes une fois, dans l’ordre, dans un script qui se lance de la même façon à chaque fois.

À la fin de cette leçon

Remarque

Je peux écrire une petite chaîne qui nettoie, relie et fait un rapport, et qui s’arrête quand un contrôle échoue.

Mots-clés

MotCe que ça veut direExemple
Chaîne de traitementdes étapes lancées dans l’ordre, chacune utilisant le résultat de la précédente
Étapeun pas de la chaîneretirer les doublons
Contrôleun test dans la chaîne qui peut l’arrêter
Code de sortiele nombre par lequel un script finit, 0 si tout va biensys.exit(1)
Reproductiblequi donne le même résultat à chaque lancement

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Des étapes dans un ordre fixe

Une chaîne de traitement est une liste d’étapes. Chacune prend un tableau et en rend un. L’ordre compte : on ne peut pas relier par la date avant que les dates soient propres.

Après chaque étape, la chaîne peut afficher combien de lignes restent. Une chute brutale est le premier signe qu’un pas s’est mal passé.

Exemple travaillé : les étapes du jour

ÉtapeCe qu’elle faitLignes attendues
lectureCharge l’export sale367
sans doublonsRetire les lignes présentes deux fois365
vrais comptesGarde les locations de 0 ou plus, en nombres363
jointureAjoute la colonne des fériés en gardant chaque jour363

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Écrire de nouveau la liste des fériés

Commande
docker exec jupyter sh -c "printf '%s\n' 'date,ferie' '2025-01-01,Nouvel An' '2025-04-21,Lundi de Pâques' '2025-05-01,Fête du Travail' '2025-05-08,Victoire 1945' '2025-07-14,Fête nationale' '2025-08-15,Assomption' '2025-11-11,Armistice' '2025-12-25,Noël' > jours-feries.csv"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Le script tient en une vingtaine de lignes

Le bloc suivant montre le script. Lisez-le d’abord. La fonction etape affiche les lignes restantes et arrête tout le script avec le code 1 s’il y en a moins que minimum.

Le nombre minimum est donné au lancement : vous choisissez la sévérité du contrôle.

steps/traitement.py

Code: python
import sys
import pandas as pd
from mess import make

minimum = int(sys.argv[1])

def etape(nom, tableau):
    print(nom, "->", len(tableau), "lignes")
    if len(tableau) < minimum:
        print("ARRET :", nom, "laisse moins de", minimum, "lignes")
        sys.exit(1)
    return tableau

make()
tableau = etape("lecture", pd.read_csv("messy.csv"))
tableau = etape("sans doublons", tableau.drop_duplicates())
tableau["hires"] = pd.to_numeric(tableau["hires"], errors="coerce")
tableau = etape("vrais comptes", tableau[tableau["hires"] >= 0])
tableau["weather"] = tableau["weather"].str.strip().str.lower()
tableau = etape("jointure", tableau.merge(pd.read_csv("jours-feries.csv"), on="date", how="left"))
tableau.to_csv("rapport.csv", index=False)
print(tableau.groupby("weather")["hires"].mean().round(1).to_string())

Écrire la chaîne dans le labo

Commande
docker exec jupyter sh -c "printf '%s\n' 'import sys' 'import pandas as pd' 'from mess import make' '' 'minimum = int(sys.argv[1])' '' 'def etape(nom, tableau):' '    print(nom, \"->\", len(tableau), \"lignes\")' '    if len(tableau) < minimum:' '        print(\"ARRET :\", nom, \"laisse moins de\", minimum, \"lignes\")' '        sys.exit(1)' '    return tableau' '' 'make()' 'tableau = etape(\"lecture\", pd.read_csv(\"messy.csv\"))' 'tableau = etape(\"sans doublons\", tableau.drop_duplicates())' 'tableau[\"hires\"] = pd.to_numeric(tableau[\"hires\"], errors=\"coerce\")' 'tableau = etape(\"vrais comptes\", tableau[tableau[\"hires\"] >= 0])' 'tableau[\"weather\"] = tableau[\"weather\"].str.strip().str.lower()' 'tableau = etape(\"jointure\", tableau.merge(pd.read_csv(\"jours-feries.csv\"), on=\"date\", how=\"left\"))' 'tableau.to_csv(\"rapport.csv\", index=False)' 'print(tableau.groupby(\"weather\")[\"hires\"].mean().round(1).to_string())' > steps/traitement.py"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Lancer avec un minimum de 300 lignes

Commande
docker exec jupyter python3 steps/traitement.py 300

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Un contrôle qui arrête la chaîne

Un contrôle ne sert que s’il peut dire non. Ici, c’est un minimum de lignes restantes. Donnez-lui un minimum que les données ne peuvent pas tenir : la chaîne s’arrête à la première étape qui le brise.

Le script finit alors avec le code 1, et ce qui l’a lancé sait que cela a échoué.

Demander au moins 365 lignes

Commande
docker exec jupyter python3 steps/traitement.py 365 || echo "code de sortie $?"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Demander au moins 400 lignes

Commande
docker exec jupyter python3 steps/traitement.py 400 || echo "code de sortie $?"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Vérifier ce que la dernière exécution a écrit

Commande
docker exec jupyter python3 -c "import pandas as pd; r=pd.read_csv('rapport.csv'); print(r.shape, r['ferie'].notna().sum(), r['date'].is_unique, r['hires'].isna().sum())"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une erreur fréquente

Attention

Beaucoup pensent qu’une chaîne qui a fini sans erreur est juste. Elle a seulement passé les contrôles que quelqu’un a écrits. Les nombres de lignes ne disent rien sur l’écriture des mots de météo. Ajoutez un contrôle pour chaque défaut déjà vu.

Le motif d’une étape, calculé en Python

Code: python
# Le motif d'une étape en Python simple : faire, annoncer, s'arrêter s'il reste trop peu de lignes.
lignes = [3, 8, 1, 9, 4, 2]
minimum = 3

def etape(nom, lignes, seuil):
    gardees = []
    for x in lignes:
        if x > seuil:
            gardees.append(x)
    print(nom, "->", len(gardees), "lignes")
    if len(gardees) < minimum:
        print("ARRET :", nom)
        return None
    return gardees

lignes = etape("garder plus de 2", lignes, 2)
if lignes is not None:
    lignes = etape("garder plus de 5", lignes, 5)
if lignes is None:
    print("arrêté")
else:
    print("terminé")
# Passez minimum à 2 et relancez.

Pour aller plus loin : ajouter un contrôle

Ajoutez à steps/traitement.py une étape qui s’arrête si un mot de météo n’est pas cloudy, rainy ou sunny. Utilisez set(tableau["weather"]) et comparez.

Essayez-la sur les données nettoyées, puis avant la ligne strip. Que repère ce contrôle que les nombres de lignes ont manqué ?

À propos de ce labo et de sa source: Lab JupyterLab de science des données : pandas, Matplotlib et scikit-learn dans le navigateur

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.