
Vous pouvez remplacer la valeur manquante (NaN) dans pandas.DataFrame et Series par n’importe quelle valeur à l’aide de la méthode fillna().
Cet article décrit le contenu suivant.
- Remplacer toutes les valeurs manquantes par la même valeur
- Remplacer les valeurs manquantes par des valeurs différentes pour chaque colonne
- Remplacez les valeurs manquantes par la moyenne, la médiane, le mode, etc. pour chaque colonne
- Remplacez les valeurs manquantes par les valeurs valides précédentes/suivantes :
method, limit
- Opérer sur place :
inplace
- Pour les pandas.Série
Utilisez interpolate() si vous souhaitez remplir les valeurs manquantes avec une interpolation linéaire ou spline.
Pour plus d’informations sur la suppression ou le comptage des valeurs manquantes, consultez les articles suivants.
Notez que non seulement NaN (Not a Number) mais aussi None est traité comme une valeur manquante dans les pandas.
Par exemple, lisez un fichier CSV avec des valeurs manquantes avec read_csv().
import pandas as pd
df = pd.read_csv('data/src/sample_pandas_normal_nan.csv')
print(df)
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 NaN NaN NaN NaN NaN
# 2 Charlie NaN CA NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen NaN CA 88.0 NaN
# 5 Frank 30.0 NaN NaN NaN
Remplacer toutes les valeurs manquantes par la même valeur
En spécifiant la valeur scalaire comme première valeur d’argument de fillna(), toutes les valeurs manquantes sont remplacées par la valeur.
print(df.fillna(0))
# name age state point other
# 0 Alice 24.0 NY 0.0 0.0
# 1 0 0.0 0 0.0 0.0
# 2 Charlie 0.0 CA 0.0 0.0
# 3 Dave 68.0 TX 70.0 0.0
# 4 Ellen 0.0 CA 88.0 0.0
# 5 Frank 30.0 0 0.0 0.0
Notez que le type de données dtype d’une colonne de nombres incluant NaN est flottant, donc même si vous remplacez NaN par un nombre entier, le type de données reste flottant. Si vous voulez le convertir en int, utilisez astype().
Remplacer les valeurs manquantes par des valeurs différentes pour chaque colonne
En spécifiant un dictionnaire dict comme première valeur d’argument de fillna(), vous pouvez attribuer des valeurs différentes pour chaque colonne.
Spécifiez un dictionnaire de {column_name : valeur}. Si un nom de colonne n’est pas spécifié, les valeurs manquantes dans sa colonne sont conservées (= non remplacées). Si la clé ne correspond pas à un nom de colonne, elle est ignorée.
print(df.fillna({'name': 'XXX', 'age': 20, 'ZZZ': 100}))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 XXX 20.0 NaN NaN NaN
# 2 Charlie 20.0 CA NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 20.0 CA 88.0 NaN
# 5 Frank 30.0 NaN NaN NaN
Vous pouvez également spécifier pandas.Series. Les étiquettes de pandas.Series correspondent à la clé de dict.
s_for_fill = pd.Series(['XXX', 20, 100], index=['name', 'age', 'ZZZ'])
print(s_for_fill)
# name XXX
# age 20
# ZZZ 100
# dtype: object
print(df.fillna(s_for_fill))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 XXX 20.0 NaN NaN NaN
# 2 Charlie 20.0 CA NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 20.0 CA 88.0 NaN
# 5 Frank 30.0 NaN NaN NaN
La moyenne de chaque colonne peut être calculée avec la méthode mean(). pandas.Series est renvoyé. NaN est exclu, mais le résultat pour une colonne où tous les éléments sont NaN est NaN.
print(df.mean())
# age 40.666667
# point 79.000000
# other NaN
# dtype: float64
Si vous spécifiez ce pandas.Series comme première valeur d’argument de fillna(), les valeurs manquantes de la colonne correspondante sont remplacées par la valeur moyenne.
print(df.fillna(df.mean()))
# name age state point other
# 0 Alice 24.000000 NY 79.0 NaN
# 1 NaN 40.666667 NaN 79.0 NaN
# 2 Charlie 40.666667 CA 79.0 NaN
# 3 Dave 68.000000 TX 70.0 NaN
# 4 Ellen 40.666667 CA 88.0 NaN
# 5 Frank 30.000000 NaN 79.0 NaN
De même, si vous souhaitez remplacer les valeurs manquantes par la médiane, utilisez la méthode median(). Si le nombre d’éléments est pair, la moyenne des deux valeurs médianes est renvoyée.
print(df.fillna(df.median()))
# name age state point other
# 0 Alice 24.0 NY 79.0 NaN
# 1 NaN 30.0 NaN 79.0 NaN
# 2 Charlie 30.0 CA 79.0 NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 30.0 CA 88.0 NaN
# 5 Frank 30.0 NaN 79.0 NaN
Le mode peut être obtenu avec la méthode mode(). Puisque mode() renvoie pandas.DataFrame, la première ligne est récupérée en tant que pandas.Series par iloc[0] dans cet exemple.
print(df.fillna(df.mode().iloc[0]))
# name age state point other
# 0 Alice 24.0 NY 70.0 NaN
# 1 Alice 24.0 CA 70.0 NaN
# 2 Charlie 24.0 CA 70.0 NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 24.0 CA 88.0 NaN
# 5 Frank 30.0 CA 70.0 NaN
Dans ces exemples, il n’y a pas de problème, mais des méthodes telles que mean() peuvent renvoyer des valeurs inattendues car elles tentent de faire fonctionner non seulement des colonnes numériques mais également d’autres types de colonnes par défaut.
Dans mean() et ainsi de suite, si l’argument numeric_only est défini sur True, seules les colonnes numériques sont traitées. Notez que les colonnes de type bool sont traitées comme True=1 et False=0 même si numeric_only=True.
Remplacez les valeurs manquantes par les valeurs valides précédentes/suivantes :method, limit
L’argument de méthode de fillna() peut être utilisé pour remplacer les valeurs manquantes par des valeurs valides précédentes/suivantes.
Si la méthode est définie sur ‘ffill’ ou ‘pad’, les valeurs manquantes sont remplacées par les valeurs valides précédentes (= remplissage vers l’avant), et si ‘bfill’ ou ‘backfill’, remplacées par les valeurs valides suivantes (= remplissage vers l’arrière).
print(df.fillna(method='ffill'))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 Alice 24.0 NY NaN NaN
# 2 Charlie 24.0 CA NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 68.0 CA 88.0 NaN
# 5 Frank 30.0 CA 88.0 NaN
print(df.fillna(method='bfill'))
# name age state point other
# 0 Alice 24.0 NY 70.0 NaN
# 1 Charlie 68.0 CA 70.0 NaN
# 2 Charlie 68.0 CA 70.0 NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 30.0 CA 88.0 NaN
# 5 Frank 30.0 NaN NaN NaN
Si method est spécifié, limit peut être utilisé pour spécifier le nombre maximum de remplacements consécutifs.
print(df.fillna(method='ffill', limit=1))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 Alice 24.0 NY NaN NaN
# 2 Charlie NaN CA NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 68.0 CA 88.0 NaN
# 5 Frank 30.0 CA 88.0 NaN
print(df.fillna(method='bfill', limit=1))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 Charlie NaN CA NaN NaN
# 2 Charlie 68.0 CA 70.0 NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 30.0 CA 88.0 NaN
# 5 Frank 30.0 NaN NaN NaN
Il peut ne pas être utilisé souvent, mais si l’argument de l’axe est défini sur 1 ou ‘columns’, les valeurs manquantes sont remplacées par les valeurs gauche et droite.
print(df.fillna(method='ffill', axis=1))
# name age state point other
# 0 Alice 24.0 NY NY NY
# 1 NaN NaN NaN NaN NaN
# 2 Charlie Charlie CA CA CA
# 3 Dave 68.0 TX 70.0 70.0
# 4 Ellen Ellen CA 88.0 88.0
# 5 Frank 30.0 30.0 30.0 30.0
print(df.fillna(method='bfill', axis=1))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 NaN NaN NaN NaN NaN
# 2 Charlie CA CA NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen CA CA 88.0 NaN
# 5 Frank 30.0 NaN NaN NaN
Les méthodes qui correspondent à l’argument method sont fournies séparément.
ffill() et pad() sont équivalents à fillna(method=’ffill’), et bfill() et backfill() sont équivalents à fillna(method=’bfill’). Vous pouvez spécifier une limite.
print(df.ffill())
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 Alice 24.0 NY NaN NaN
# 2 Charlie 24.0 CA NaN NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 68.0 CA 88.0 NaN
# 5 Frank 30.0 CA 88.0 NaN
print(df.bfill(limit=1))
# name age state point other
# 0 Alice 24.0 NY NaN NaN
# 1 Charlie NaN CA NaN NaN
# 2 Charlie 68.0 CA 70.0 NaN
# 3 Dave 68.0 TX 70.0 NaN
# 4 Ellen 30.0 CA 88.0 NaN
# 5 Frank 30.0 NaN NaN NaN
Opérer sur place :inplace
Comme indiqué dans les exemples ci-dessus, par défaut, un nouvel objet est renvoyé et l’objet d’origine n’est pas modifié, mais si inplace=True, l’objet d’origine lui-même est mis à jour.
df.fillna(0, inplace=True)
print(df)
# name age state point other
# 0 Alice 24.0 NY 0.0 0.0
# 1 0 0.0 0 0.0 0.0
# 2 Charlie 0.0 CA 0.0 0.0
# 3 Dave 68.0 TX 70.0 0.0
# 4 Ellen 0.0 CA 88.0 0.0
# 5 Frank 30.0 0 0.0 0.0
Pour les pandas.Série
Vous pouvez également utiliser fillna() de pandas.Series comme dans les exemples précédents de pandas.DataFrame.
s = pd.read_csv('data/src/sample_pandas_normal_nan.csv')['age']
print(s)
# 0 24.0
# 1 NaN
# 2 NaN
# 3 68.0
# 4 NaN
# 5 30.0
# Name: age, dtype: float64
print(s.fillna(100))
# 0 24.0
# 1 100.0
# 2 100.0
# 3 68.0
# 4 100.0
# 5 30.0
# Name: age, dtype: float64
print(s.fillna({1: 100, 4: -100}))
# 0 24.0
# 1 100.0
# 2 NaN
# 3 68.0
# 4 -100.0
# 5 30.0
# Name: age, dtype: float64
print(s.fillna(method='bfill', limit=1))
# 0 24.0
# 1 NaN
# 2 68.0
# 3 68.0
# 4 30.0
# 5 30.0
# Name: age, dtype: float64
Les méthodes qui correspondent à l’argument de la méthode sont également fournies.
print(s.bfill(limit=1))
# 0 24.0
# 1 NaN
# 2 68.0
# 3 68.0
# 4 30.0
# 5 30.0
# Name: age, dtype: float64