Les valeurs manquantes (NaN) dans pandas en Python : détecter, supprimer, remplacer
Vous importez un fichier clients, vous lancez une moyenne... et le résultat est faux, ou une colonne de montants refuse obstinément d'être numérique. Dans neuf cas sur dix, le coupable est le même : des valeurs manquantes mal repérées.
En science des données, le nettoyage occupe une large part du temps, et la gestion des valeurs manquantes en est l'étape la plus fréquente. La bonne nouvelle : la bibliothèque Python pandas simplifie énormément ce travail. Dans ce guide, on voit comment traiter les données manquantes pas à pas : la façon dont une donnée absente est représentée, comment la détecter, puis comment choisir entre la supprimer et la remplacer. Tous les exemples ont été testés avec la version 3 de la librairie, qui a changé plusieurs habitudes encore présentes dans beaucoup de tutoriels en ligne.
Pourquoi le traitement des données manquantes est indispensable
Dans les ensembles de données réels (exports de CRM, fichiers Excel, formulaires), les valeurs manquantes peuvent venir d'un champ non obligatoire, d'une erreur de saisie ou d'une jointure entre deux tables. Si on les ignore, elles faussent les calculs : une moyenne ne porte plus sur les bonnes lignes, un modèle de Machine Learning refuse de s'entraîner, un graphique affiche des trous. Et quand plusieurs colonnes contiennent des valeurs manquantes, le nombre de lignes complètes chute vite : l'impact de ces valeurs manquantes peut être bien plus fort qu'on ne l'imagine.
La démarche se fait en trois temps : repérer les cellules vides, mesurer leur ampleur, puis décider de les supprimer ou de les remplacer. C'est exactement le plan de cet article.
Exemple de DataFrame avec des valeurs manquantes
On part d'un petit fichier clients.csv, typique d'un export réel : une ville oubliée, des âges non renseignés, et un chiffre d'affaires saisi « N/A » ou « - » quand il n'est pas connu.
client,ville,age,ca_annuel,date_inscription
Dupont,Paris,34,1200,2026-01-15
Martin,,41,N/A,2026-02-03
Bernard,Lyon,,950,
Petit,Lyon,29,-,2026-03-10
Durand,Paris,,1800,2026-03-22NaN, None, NaT : comment pandas représente une valeur manquante
Selon le type de données de la colonne, une donnée absente s'affiche différemment :
NaN (« Not a Number », pas un nombre) : l'absence « classique », notamment pour les nombres
NaT (« Not a Time ») : son équivalent pour les dates
None : la valeur vide de Python, que pandas traite comme absente
pd.NA : le marqueur des types « nullables » comme Int64, qui permettent d'avoir des entiers avec des trous
Les méthodes isna(), dropna() et fillna() reconnaissent toutes ces formes, sur un DataFrame ou Series indifféremment. Vous n'avez pas à les traiter séparément, quels que soient les différents types de données de vos colonnes.
Importer les données avec pandas : faire reconnaître les « faux vides »
Premier piège : pandas ne sait pas que « N/A » ou « - » signifient « inconnu ». Il lit la colonne ca_annuel comme du texte, et vous ne pourrez ni la sommer ni en faire la moyenne. Indiquez-lui ces marqueurs dès la lecture du fichier :
import pandas as pd
import numpy as np
clients = pd.read_csv(
"clients.csv",
na_values=["N/A", "-"],
parse_dates=["date_inscription"]
)Résultat :
client ville age ca_annuel date_inscription
0 Dupont Paris 34.0 1200.0 2026-01-15
1 Martin NaN 41.0 NaN 2026-02-03
2 Bernard Lyon NaN 950.0 NaT
3 Petit Lyon 29.0 NaN 2026-03-10
4 Durand Paris NaN 1800.0 2026-03-22La colonne ca_annuel est maintenant numérique. Notez au passage que la colonne age est passée en décimal (34.0) : une colonne d'entiers classique ne peut pas contenir de cellule vide. On y revient dans les erreurs fréquentes.
Le fichier est déjà chargé et contient des chaînes vides ou des espaces ? Transformez-les en valeurs manquantes à l’aide de replace() :
clients["ville"] = clients["ville"].replace(r"^\s*$", np.nan, regex=True)Détecter les valeurs manquantes avec pandas : isna()
La méthode isna() renvoie True pour chaque cellule vide et False pour les valeurs non vides. C'est l'outil de base pour la détection des valeurs absentes : appliquée au DataFrame pandas entier, elle renvoie un tableau de booléens de la même taille.
Pour afficher les lignes qui ont au moins une donnée absente, combinez isna() avec any() (voir notre article sur les méthodes any() et all()) :
clients[clients.isna().any(axis=1)]Ici, quatre clients sur cinq ressortent : seul Dupont a une fiche complète.
Compter les valeurs manquantes dans les colonnes
Combinée à sum(), isna() donne le nombre de cellules vides dans chacune des colonnes. C'est le tout premier réflexe à avoir sur un nouveau jeu de données, pour mesurer la présence de valeurs NaN avant de décider quoi que ce soit :
clients.isna().sum()Résultat :
client 0
ville 1
age 2
ca_annuel 2
date_inscription 1En remplaçant sum() par mean(), vous obtenez la proportion de cellules vides, souvent plus parlante :
(clients.isna().mean() * 100).round(1)Résultat : 40 % des âges et 40 % des chiffres d'affaires sont absents. Un chiffre à connaître avant toute décision.
Le piège des valeurs NaN : ne jamais comparer avec ==
C'est l'erreur la plus fréquente chez les débutants :
clients[clients["age"] == np.nan] # renvoie un tableau VIDE
clients[clients["age"].isna()] # renvoie bien les 2 clients sans âgePar définition, NaN n'est égal à rien, pas même à lui-même : np.nan == np.nan vaut False. Une comparaison avec == ne trouvera donc jamais vos cellules vides. Utilisez toujours isna(), ou notna() pour repérer les valeurs non vides.
Supprimer les lignes avec des valeurs non renseignées : dropna()
dropna() supprime les lignes contenant au moins une donnée absente. Utilisée telle quelle, elle est radicale :
clients.dropna()Ici, il ne reste qu'un seul client sur cinq. C'est rarement ce que l'on veut. Trois paramètres permettent d'être plus précis :
subset : ne regarder que certaines colonnes. clients.dropna(subset=["ca_annuel"]) supprime seulement les clients dont le chiffre d'affaires est inconnu (il en reste 3).
thresh : garder les lignes qui ont au moins N valeurs non vides. clients.dropna(thresh=4) conserve les clients qui ont au plus une information absente.
how="all" : ne supprimer que les lignes entièrement vides, très utile pour les lignes blanches en fin de fichier Excel.
Pour supprimer des colonnes plutôt que des lignes (par exemple une colonne vide à 90 %), ajoutez axis=1.
Remplacer les valeurs manquantes avec fillna()
Supprimer, c'est perdre de l'information. Souvent, mieux vaut compléter les cellules vides. La fonction pandas fillna() propose plusieurs stratégies, selon la nature de la donnée.
Remplacer des valeurs manquantes par une valeur fixe
Passez un dictionnaire à fillna() pour choisir la valeur de remplacement de chaque colonne :
clients = clients.fillna({"ville": "Inconnue", "ca_annuel": 0})Réfléchissez avant de mettre 0 : un chiffre d'affaires inconnu n'est pas un chiffre d'affaires nul. Remplacer par 0 fera baisser toutes vos moyennes.
La médiane ou la moyenne de la colonne
Pour une donnée numérique comme l'âge, on remplace souvent par la médiane, moins sensible aux valeurs extrêmes que la moyenne :
clients["age"] = clients["age"].fillna(clients["age"].median())La médiane de son groupe
Plus fin : remplacer l'âge absent par la médiane des clients de la même ville. On combine fillna() avec groupby() et transform() :
mediane_ville = clients.groupby("ville")["age"].transform("median")
clients["age"] = clients["age"].fillna(mediane_ville)Bernard, à Lyon, reçoit l'âge médian des Lyonnais (29 ans) et Durand celui des Parisiens (34 ans). Si groupby() et transform() ne vous sont pas familiers, lisez notre guide de groupby dans pandas.
La valeur précédente ou suivante : ffill() et bfill()
Pour des séries chronologiques (un stock, un cours, un relevé de compteur), on recopie souvent la dernière valeur connue :
s = pd.Series([10.0, None, None, 16.0])
s.ffill() # [10.0, 10.0, 10.0, 16.0] valeur précédente
s.bfill() # [10.0, 16.0, 16.0, 16.0] valeur suivanteUne estimation entre deux points : interpolate()
Si la grandeur évolue de façon régulière, interpolate() estime les cellules vides à partir de leurs voisines :
s.interpolate() # [10.0, 12.0, 14.0, 16.0]Pour comprendre ce que fait une interpolation et choisir la bonne méthode, voir notre article sur l'interpolation.
Traitement des valeurs manquantes : supprimer ou remplacer ?
Situation | Stratégie conseillée |
Quelques lignes vides, beaucoup de données | dropna() avec subset |
Colonne vide à plus de 60-70 % | Supprimer la colonne (axis=1) |
Donnée numérique, cellules vides au hasard | fillna() avec la médiane |
La valeur dépend d'une catégorie (ville, produit) | Médiane du groupe avec transform() |
Série chronologique | ffill() ou interpolate() |
Donnée texte (ville, catégorie) | fillna("Inconnue") pour garder la ligne |
L'absence a un sens métier (pas de commande) | fillna(0), en connaissance de cause |
Dans tous les cas, gardez une trace de ce que vous avez fait. Une astuce simple : créez une colonne indicatrice avant de remplacer, par exemple clients["age_estime"] = clients["age"].isna().
4 erreurs fréquentes (et ce qui a changé avec pandas 3)
1. Utiliser fillna(method="ffill")
Beaucoup de tutoriels montrent encore df.fillna(method="ffill"). Cette syntaxe, dépréciée depuis pandas 2.1, provoque désormais une erreur TypeError dans la version 3. Utilisez directement ffill() ou bfill().
2. Utiliser inplace=True sur une colonne
Le code suivant ne modifie plus votre tableau dans la version 3, qui affiche à la place un avertissement ChainedAssignmentError :
clients["age"].fillna(0, inplace=True) # ne fait rien sur clients
clients["age"] = clients["age"].fillna(0) # la bonne écriturePrenez l'habitude de toujours réaffecter le résultat : c'est plus lisible et cela fonctionne dans toutes les versions.
3. S'étonner qu'une colonne d'entiers devienne décimale
Une seule cellule vide suffit pour qu'une colonne d'entiers passe en nombres décimaux (34 devient 34.0). Pour garder des entiers avec des trous, utilisez le type nullable Int64 : clients["age"].astype("Int64"). Tous les détails dans notre article le plus lu : comment changer le type d'une colonne dans pandas.
4. Remplacer avant de découper ses données en Machine Learning
Si vous préparez un modèle, calculez la médiane de remplacement sur les données d'entraînement uniquement, puis appliquez-la aux données de test. Sinon, des informations du jeu de test « fuitent » dans l'entraînement et vos scores sont trop optimistes. On détaille l'ordre des opérations dans les grandes étapes d'un projet de Machine Learning.
En résumé : gérer les valeurs NaN en Python
À l'import, déclarez les faux vides avec na_values.
Comptez avec isna().sum() et isna().mean().
Ne cherchez jamais une cellule vide avec ==.
Supprimez avec dropna() en ciblant les colonnes (subset), ou remplacez avec fillna(), ffill() ou interpolate() selon la nature de la donnée.
Réaffectez toujours le résultat plutôt que d'utiliser inplace=True.
Nettoyer les données est au cœur de la préparation des données et de l’analyse : c'est pourquoi nous y consacrons un temps important, sur des jeux de données réels, dans notre formation Python pour l'analyse de données. Vous y découvrirez aussi d'autres astuces pandas pour manipuler les structures de données courantes. Pour aller jusqu'aux modèles prédictifs, découvrez notre formation Python Machine Learning. Ces formations sont éligibles au CPF.
Questions fréquentes sur les données manquantes dans pandas
Comment repérer les cellules vides dans un tableau ?
Utilisez clients.isna().sum() pour obtenir le nombre de cellules vides par colonne, et clients.isna().sum().sum() pour le total du tableau. clients.isna().mean() donne la proportion par colonne.
Quelle différence entre isna() et isnull() ?
Aucune : isnull() est un alias de isna(). Les deux renvoient True pour les cellules vides, sous toutes les formes vues plus haut. Il en va de même pour notna() et notnull().
Comment remplacer les NaN par 0 dans pandas ?
df.fillna(0) remplace toutes les cellules vides du tableau par 0. Pour une seule colonne, écrivez df["colonne"] = df["colonne"].fillna(0). Vérifiez cependant que 0 a un sens métier, sinon vos moyennes seront faussées.
Pourquoi fillna(method="ffill") ne fonctionne plus ?
Le paramètre method a été déprécié dans pandas 2.1 puis retiré dans la version 3, où il provoque une erreur. Remplacez-le par ffill() (valeur précédente) ou bfill() (valeur suivante).
Faut-il supprimer ou remplacer les données absentes ?
Cela dépend de leur quantité et de leur signification. Si elles sont rares, la suppression ciblée (dropna avec subset) est acceptable. Si elles sont nombreuses ou si chaque ligne compte, mieux vaut compléter les cellules par une valeur cohérente : médiane, médiane du groupe, valeur précédente ou interpolation. Pour bien gérer les données manquantes : mesurer, décider, puis documenter.


