All guides
IntermediateSelf-pacedFree GuideSection 29/95

pandas — Nettoyage et transformation des données

Practise development foundations: programming, web, APIs, data and AI tools. Work through sections and exercises to build your first projects.

The full lessons for this course are currently available in French. Use the section menu to navigate the French course.

💡

Free content, available without an account. Tools and models change: use the current model guide to check their versions. Models and sources

Section 11.2.9 : pandas — Nettoyage et transformation des données

🎯 Objectif pédagogique

Nettoyer des données réelles (valeurs manquantes, doublons, types incorrects, anomalies) avec pandas. Vous serez capable de prendre un jeu de données "sale" et de le préparer pour l'analyse — la compétence qui prend 80% du temps d'un data scientist.


Le vrai travail de la data : le nettoyage

Marc découvre une vérité que tout data scientist connaît : 80% du temps en data science n'est pas consacré à l'analyse ou au machine learning, c'est au nettoyage des données. Données manquantes, doublons, formats incohérents, erreurs de saisie...

"Dans la finance, je passais des journées à nettoyer les tableaux Excel des collègues. En Python, ça prend 10 minutes."

Valeurs manquantes (NaN)

import pandas as pd
import numpy as np

# Données réalistes (sales !)
df = pd.DataFrame(\{
    'company': ['Google', 'Meta', None, 'Datadog', 'Stripe', 'Google'],
    'position': ['Frontend', 'React Dev', 'Full-Stack', None, 'Backend', 'Frontend'],
    'salary': [75000, np.nan, 70000, 65000, np.nan, 75000],
    'status': ['interview', 'applied', 'applied', 'rejected', 'offer', 'interview'],
    'date': ['2026-03-01', '2026-03-05', '2026-02-15', '2026-02-01', None, '2026-03-01']
\})

# Détecter les NaN
print(df.isnull())              # Tableau de booléens
print(df.isnull().sum())        # Nombre de NaN par colonne
# company     1
# position    1
# salary      2
# status      0
# date        1

print(df.isnull().sum().sum())  # Total de NaN : 4

# Supprimer les lignes avec NaN
df_clean = df.dropna()              # Toutes les lignes avec au moins 1 NaN
df_clean = df.dropna(subset=['company', 'status'])  # NaN seulement dans ces colonnes

# Remplir les NaN
df['salary'] = df['salary'].fillna(df['salary'].median())   # Médiane
df['company'] = df['company'].fillna('Inconnue')             # Valeur par défaut

# Interpolation (séries temporelles)
df['salary'] = df['salary'].interpolate()

Doublons

# Détecter les doublons
print(df.duplicated())                      # Lignes entièrement dupliquées
print(df.duplicated(subset=['company', 'position']))  # Doublons sur ces colonnes

print(f"Doublons : \{df.duplicated().sum()\}")

# Supprimer les doublons
df = df.drop_duplicates()
df = df.drop_duplicates(subset=['company', 'position'], keep='last')  # Garder le dernier

Types de données

# Vérifier les types
print(df.dtypes)
# company     object  ← texte
# salary      float64 ← numérique (float à cause des NaN)
# date        object  ← PROBLÈME : c'est du texte, pas une date !

# Convertir les types
df['date'] = pd.to_datetime(df['date'])
df['salary'] = df['salary'].astype(int)
df['status'] = df['status'].astype('category')  # Optimise la mémoire

# Catégories ordonnées
status_order = ['applied', 'interview', 'offer', 'rejected']
df['status'] = pd.Categorical(df['status'], categories=status_order, ordered=True)

Nettoyage de texte

# Problèmes courants
df['company'] = df['company'].str.strip()           # Espaces en trop
df['company'] = df['company'].str.title()            # Capitalisation
df['position'] = df['position'].str.lower()          # Minuscules
df['company'] = df['company'].str.replace(r'\s+', ' ', regex=True)  # Espaces multiples

# Standardiser les valeurs
status_map = \{
    'en cours': 'applied',
    'candidaté': 'applied',
    'entretien': 'interview',
    'refusé': 'rejected',
    'accepté': 'offer'
\}
df['status'] = df['status'].replace(status_map)

Anomalies (outliers)

# Détection par IQR (Interquartile Range)
Q1 = df['salary'].quantile(0.25)
Q3 = df['salary'].quantile(0.75)
IQR = Q3 - Q1

lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR

outliers = df[(df['salary'] < lower) | (df['salary'] > upper)]
print(f"Anomalies de salaire : \{len(outliers)\}")
print(outliers)

# Supprimer ou plafonner
df = df[(df['salary'] >= lower) & (df['salary'] <= upper)]
# OU plafonner
df['salary'] = df['salary'].clip(lower=lower, upper=upper)

Le pipeline de nettoyage standard

Marc a mémorisé l'ordre :

  1. →Types → convertir dates, nombres, catégories
  2. →Doublons → identifier et supprimer
  3. →NaN → compter, décider (supprimer ou remplir)
  4. →Texte → normaliser la casse, les espaces
  5. →Anomalies → détecter et traiter
  6. →Validation → assert final (shape, nulls, types)

🏋️ Exercice pratique (25 minutes)

# Données sales à nettoyer
dirty = pd.DataFrame(\{
    'Company': ['Google ', 'GOOGLE', 'meta', ' Meta', 'Stripe', None, 'Datadog'],
    'Salary': [75000, 75000, 80000, 80000, 70000, 50000, -1],
    'Status': ['interview', 'interview', 'Applied', 'applied', 'OFFER', 'applied', 'rejected'],
    'Date': ['2026-03-01', '2026-03-01', '2026-03-05', 'invalid', '2026-02-15', '2026-03-10', '2026-02-01']
\})

# Nettoyez :
# 1. Normalisez Company (strip, title case)
# 2. Normalisez Status (minuscules)
# 3. Supprimez les doublons (Google apparaît 2x)
# 4. Gérez les NaN dans Company
# 5. Corrigez le salaire -1 (→ NaN → médiane)
# 6. Convertissez Date en datetime (gérez 'invalid' → NaT)
Quick Check

Pourquoi le nettoyage des données représente-t-il ~80% du travail d'un data scientist ?

Quick Check

Que fait df.dropna(subset=['company']) ?

Your progress

Progress is self-reported and stored in your browser. The final completion record is not a qualification or an independent assessment.

View progress and completion record

Learn AI, from prompts to agents

15 free guidesQuizzes, diagrams and workshopsNo account needed

One practical AI workflow in your inbox

Methods, resources and new exercises. Free, unsubscribe at any time.