web-dev-qa-db-fra.com

Pandas: SettingWithCopyWarning

J'aimerais remplacer les valeurs dans une variable PandasDataFrame supérieure à un nombre arbitraire (100 dans ce cas) par NaN (les valeurs aussi grandes indiquent une expérience manquée). Auparavant, je l'utilisais pour remplacer des valeurs indésirables:

sve2_all[sve2_all[' Hgtot ng/l'] > 100] = np.nan

Cependant, j'ai eu l'erreur suivante:

-c:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
C:\Users\AppData\Local\Enthought\Canopy32\User\lib\site-packages\pandas\core\indexing.py:346: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
self.obj[item] = s

De cette question StackExchange , il semble que parfois cet avertissement peut être ignoré, mais je ne peux pas suivre la discussion assez bien pour être certain que cela s'applique à ma situation. Est-ce que l'avertissement me dit fondamentalement que je vais écraser certaines des valeurs de ma DataFrame?

Edit: Autant que je sache, tout s'est comporté comme il se doit. En guise de suivi, ma méthode de remplacement des valeurs non standard? Y a-t-il une meilleure façon de remplacer les valeurs?

18
Jason

Comme suggéré dans le message d'erreur, vous devriez utiliser loc pour faire ceci:

sve2_all.loc[sve2_all['Hgtot ng/l'] > 100] = np.nan

L’avertissement est là pour vous empêcher de modifier une copie (ici sve2_all[sve2_all[' Hgtot ng/l'] > 100] est potentiellement une copie, et si c’est le cas, aucune modification ne changerait le cadre original. Il se peut que cela fonctionne correctement dans certains cas, mais que ne peut garantir que cela fonctionnera dans tous les cas ... utilisez-le à vos risques et périls (considérez-vous averti!;)).

23
Andy Hayden

--- Problème résolu pour moi ---

J'ai eu cette erreur en guerre quand j'ai essayé de convertir float -> int même si j'ai utilisé la commande ".loc". mon erreur est que j'ai filtré mon dataFrame (avec des masques) avant l'opération afin que la conversion ne se produise que dans une petite partie de l'élément/de la colonne dataframe, le résultat était une colonne de type mixte qui crée une configuration. J'ai résolu le problème en convertissant le bloc de données avant les masques (filtrage des données), j'espère que cela vous aidera.

2
ilyes

Je recevais cet avertissement lorsque j'essayais de réinitialiser le contenu d'un DataFrame complet, mais je ne pouvais pas le résoudre à l'aide de loc ou iloc:

df.loc[:, :] = new_values # SettingWithCopyWarning
df.iloc[:, :] = new_values # SettingWithCopyWarning

Mais résoudre le ndarray contenu en tant que données a résolu le problème:

df.values[:, :] = new_values # no warnings and desired behavior
2
Marshall Farrier

Comme suggéré par d'autres utilisateurs, vous pouvez essayer:

myindex = sve2_all[' Hgtot ng/l'] > 100

sve2_all.loc[myindex, 'yourcolumn'] = np.nan

N'oubliez pas que si vous rencontrez des problèmes lors de la création de tableaux croisés croisés dynamiques (pivot_table row mot-clé non pris en charge par pandas 0.16.0 #417), vous devez utiliser la nouvelle syntaxe d'index et de colonnes au lieu de lignes et de colonnes. https://github.com/yhat/ggplot/issues/417

Voir également:

Pandas SettingWithCopyWarning

http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

1
George Zoto