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

97

Je voudrais remplacer les mauvaises valeurs dans une colonne d'un dataframe par 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

Cependant, la dernière ligne échoue et lance un avertissement car elle 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.

Mark Morrisson
la source

Réponses:

122

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

Ce que vous essayez s'appelle l'indexation de chaîne: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

Vous pouvez utiliser locpour vous assurer de fonctionner sur 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
EdChum
la source
13

Bien que l'utilisation replacesemble résoudre le problème, je voudrais proposer une alternative. Problème avec le mélange de valeurs numériques et de certaines chaînes dans la colonne pour ne pas remplacer les chaînes par np.nan, mais pour rendre la colonne entière correcte. Je parierais que la colonne d'origine est probablement de type objet

Name: y, dtype: object

Ce dont vous avez vraiment besoin, c'est d'en faire une colonne numérique (elle aura le type approprié et sera beaucoup plus rapide), avec toutes les valeurs non numériques 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 à une valeur numérique à devenir NaN. Le type de colonne serait

Name: y, dtype: float64
Séverin Pappadeux
la source
10

Vous pouvez utiliser remplacer:

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

Tenez également compte du inplaceparamètre pour replace. Vous pouvez faire quelque chose comme:

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

Cela remplacera toutes les instances du df sans créer de copie.

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

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

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

Référence: Pandas Latest - Replace

jmorrison
la source
1
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 en un seul appel pour pouvoir le modifier.

jeremie benichou
la source
0

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 [18]: df.y [df.y == "N / A"] = np.nan

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

Depuis pandas 1.0.0, vous n'avez plus besoin d'utiliser numpy pour créer des valeurs nulles dans votre dataframe. Au lieu de cela, vous pouvez simplement utiliser pandas.NA (qui est de type pandas._libs.missing.NAType), il sera donc traité comme nul dans le dataframe mais ne sera pas nul en dehors du contexte dataframe.

slevin886
la source