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. .