web-dev-qa-db-fra.com

Comment définir une cellule sur NaN dans un cadre de données de pandas

Je voudrais remplacer les mauvaises valeurs dans une colonne d'un cadre de données par des NaN.

mydata = {'x' : [10, 50, 18, 32, 47, 20], 'y' : ['12', '11', 'N/A', '13', '15', 'N/A']}
df = pd.DataFrame(mydata)

df[df.y == 'N/A']['y'] = np.nan

Bien que la dernière ligne échoue et jette un avertissement parce que cela fonctionne sur une copie de df. Alors, quelle est la bonne façon de gérer cela? J'ai vu de nombreuses solutions avec iloc ou ix, mais ici, je dois utiliser une condition booléenne.

55
Mark Morrisson

utilisez simplement replace:

In [106]:
df.replace('N/A',np.NaN)

Out[106]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN

Vous essayez d’appeler l’indexation en chaîne: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

Vous pouvez utiliser loc pour vous assurer que vous utilisez le dF d'origine:

In [108]:
df.loc[df['y'] == 'N/A','y'] = np.nan
df

Out[108]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN
68
EdChum

Bien que l’utilisation de replace semble résoudre le problème, j’aimerais proposer une alternative. Problème lié au mélange de valeurs numériques et de certaines valeurs de chaîne dans la colonne: ne pas remplacer les chaînes par np.nan, mais rendre toute la colonne correcte. Je parierais que la colonne d'origine est probablement d'un type d'objet

Name: y, dtype: object

Ce dont vous avez vraiment besoin, c’est d’en faire une colonne numérique (le type sera approprié et serait beaucoup plus rapide), toutes les valeurs non numériques étant remplacées par NaN.

Ainsi, un bon code de conversion serait

pd.to_numeric(df['y'], errors='coerce')

Spécifiez errors='coerce' pour forcer les chaînes qui ne peuvent pas être analysées avec une valeur numérique à devenir NaN. Le type de colonne serait

Name: y, dtype: float64
8
Severin Pappadeux

Vous pouvez utiliser remplacer:

df['y'] = df['y'].replace({'N/A': np.nan})

Notez également le paramètre inplace pour replace. Vous pouvez faire quelque chose comme:

df.replace({'N/A': np.nan}, inplace=True)

Cela remplacera toutes les occurrences de la df sans créer de copie.

De même, si vous rencontrez d'autres types de valeurs inconnues telles que chaîne vide ou valeur Aucune:

df['y'] = df['y'].replace({'': np.nan})

df['y'] = df['y'].replace({None: np.nan})

Référence: Pandas Latest - Remplacer

4
jmorrison
df.loc[df.y == 'N/A',['y']] = np.nan

Cela résout votre problème. Avec le double [], vous travaillez sur une copie du DataFrame. Vous devez spécifier l'emplacement exact dans un appel pour pouvoir le modifier.

0
jeremie benichou

Vous pouvez essayer ces extraits.

 Dans [16]: mydata = {'x': [10, 50, 18, 32, 47, 20], 'y': ['12', '11', 'N/A', '13 ',' 15 ',' N/A ']} 
 Dans [17]: df = pd.DataFrame (mydata) 
.. dans. N/A "] = np.nan 

 Sortie [19]: df 
 x y 
 0 10 12 
 1 50 11 
 2 18 NaN 
 3 32 13 
 4 47 15 
 5 20 NaN 
0
rolandpeng