python pandas chained-assignment

python - Los pandas siguen recibiendo SettingWithCopyWarning incluso después de usar.loc



chained-assignment (2)

Lo resuelvo creando una copia del marco de datos:

complete = train.copy()

Al principio, intenté escribir un código similar a este:

import numpy as np import pandas as pd np.random.seed(2016) train = pd.DataFrame(np.random.choice([np.nan, 1, 2], size=(10, 3)), columns=[''Age'', ''SibSp'', ''Parch'']) complete = train.dropna() complete[''AgeGt15''] = complete[''Age''] > 15

Después de obtener SettingWithCopyWarning, intenté usar.loc:

complete.loc[:, ''AgeGt15''] = complete[''Age''] > 15 complete.loc[:, ''WithFamily''] = complete[''SibSp''] + complete[''Parch''] > 0

Sin embargo, sigo recibiendo la misma advertencia. ¿Lo que da?


Nota: A partir de la versión 0.24 de pandas, is_copy está en desuso y se eliminará en una versión futura. Si _is_copy existe el atributo privado _is_copy , el guión bajo indica que este atributo no es parte de la API pública y, por lo tanto, no se debe depender de él. Por lo tanto, en el futuro, parece que la única forma adecuada de silenciar SettingWithCopyWarning será hacerlo globalmente:

pd.options.mode.chained_assignment = None

Cuando se ejecuta complete = train.dropna() , dropna puede devolver una copia, por lo que, por precaución, Pandas establece complete.is_copy en un valor Truthy:

In [220]: complete.is_copy Out[220]: <weakref at 0x7f7f0b295b38; to ''DataFrame'' at 0x7f7eee6fe668>

Esto le permite a Pandas avisarle más tarde, cuando se complete[''AgeGt15''] = complete[''Age''] > 15 que puede estar modificando una copia que no tendrá efecto en el train . Para los principiantes esto puede ser una advertencia útil. En su caso, parece que no tiene intención de modificar el train indirectamente modificando complete . Por lo tanto, la advertencia es solo una molestia sin sentido en su caso.

Puede silenciar la advertencia configurando,

complete.is_copy = False # deprecated as of version 0.24

Esto es más rápido que hacer una copia real, y SettingWithCopyWarning la SettingWithCopyWarning de SettingWithCopyWarning (en el punto donde se llama _check_setitem_copy ):

def _check_setitem_copy(self, stacklevel=4, t=''setting'', force=False): if force or self.is_copy: ...

Si está realmente seguro de saber lo que está haciendo, puede apagar el SettingWithCopyWarning globalmente con

pd.options.mode.chained_assignment = None # None|''warn''|''raise''

Una forma alternativa de silenciar la advertencia es hacer una nueva copia:

complete = complete.copy()

Sin embargo, es posible que no desee hacer esto si el DataFrame es grande, ya que la copia puede tomar una cantidad considerable de tiempo y memoria, y es completamente inútil (excepto por silenciar una advertencia ) si sabe que ya es una copia completa. .