Tous les guides
IntermédiaireÀ votre rythmeGuide gratuitSection 29/95

pandas — Nettoyage et transformation des données

Pratiquez les fondations du développement : programmation, web, API, données et usages de l’IA. Des sections et exercices pour construire vos premiers projets.

💡

Contenu gratuit, accessible sans compte. Les outils et modèles évoluent : consultez le dossier actuel pour vérifier leurs versions. Modèles et 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)
Vérification rapide

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

Vérification rapide

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

Votre progression

Cette progression est déclarative et conservée dans votre navigateur. L’attestation finale ne constitue pas un diplôme ni une évaluation indépendante.

Voir ma progression et mon attestation

Apprendre l’IA, du premier prompt aux agents

15 guides gratuitsQuiz, schémas et ateliersSans compte

Un cas pratique IA dans votre boîte mail

Méthodes, ressources et nouveaux exercices. Gratuit, avec désinscription à tout moment.