J'ai un fichier csv que je convertis en panda dans Python 3.7. Je veux ensuite vérifier si certaines cellules ont NaN (c'est-à-dire qu'elles sont vides dans mon cas) et seulement dans ce cas, je veux remplacer le contenu de la cellule par une autre valeur.

Je sélectionne la cellule avec des valeurs dans d'autres cellules dans d'autres colonnes (colonnes family_name et first_name) sur la même ligne. Voici un MWE:

import csv
import pandas as pd
import numpy as np
df = pd.DataFrame({"family_name":["smith", "duboule", "dupont"], "first_name":["john","jean-paul", "luc"], "weight":[70, 85, pd.np.nan]})
value_to_replace = 90
if df["weight"][(df["family_name"] == "dupont") & (df["first_name"] == "luc")] == pd.np.nan:
    df["weight"][(df["family_name"] == "dupont") & (df["first_name"] == "luc")] = value_to_replace

J'obtiens l'erreur suivante:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mymac/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py", line 1576, in __nonzero__
    .format(self.__class__.__name__))
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

J'ai également essayé d'ajouter .bool() == True dans le formulaire suivant, mais j'ai reçu le même message d'erreur:

if pd.isna(df["weight"][(df["family_name"] == family_name) & (df["first_name"] == first_name)]).bool() == True:
    df["weight"][(df["family_name"] == "dupont") & (df["first_name"] == "luc")] = value_to_replace
0
ecjb 14 mars 2019 à 21:43

2 réponses

Meilleure réponse

Utilisez np.where

Fonctionne comme suit : np.where(condition, true value, false value)

df['weight'] = np.where((df.family_name == 'dupont') & (df.first_name == 'luc'), value_to_replace, df.weight)

print(df)
  family_name first_name  weight
0       smith       john    70.0
1     duboule  jean-paul    85.0
2      dupont        luc    90.0

Modifier après le commentaire de l'OP
Seulement si le poids est NaN, vous pouvez utiliser .isnull :

df['weight'] = np.where((df.family_name == 'dupont') & (df.first_name == 'luc') & (df.weight.isnull()), value_to_replace, df.weight)
2
Erfan 14 mars 2019 à 19:08

Supprimez toutes vos instructions if et utilisez ceci

df.loc[ (df["family_name"] == "dupont") & 
        (df["first_name"] == "luc") & 
        (df["weight"].isnull()), 'weight'] = value_to_replace

Je vous suggère de lire l'API pandas pour savoir comment loc sélectionner/modifier des données

1
Terry 14 mars 2019 à 19:10