Pandas: asignaciones encadenadas [duplicado]
He estado leyendo este enlace sobre "Devolver una vista frente a una copia". Realmente no entiendo cómo funciona el concepto de asignación encadenada en Pandas y cómo lo afecta el uso de .ix()
, .iloc()
o ..loc()
Recibo las SettingWithCopyWarning
advertencias para las siguientes líneas de código, donde data
hay un marco de datos de Panda y amount
un nombre de columna (Serie) en ese marco de datos:
data['amount'] = data['amount'].astype(float)
data["amount"].fillna(data.groupby("num")["amount"].transform("mean"), inplace=True)
data["amount"].fillna(mean_avg, inplace=True)
Al observar este código, ¿es obvio que estoy haciendo algo subóptimo? Si es así, ¿puede indicarme las líneas de código de reemplazo?
Soy consciente de la siguiente advertencia y me gusta pensar que las advertencias en mi caso son falsos positivos:
Las advertencias/excepciones de asignaciones encadenadas tienen como objetivo informar al usuario de una asignación posiblemente no válida. Puede haber falsos positivos; situaciones en las que se informa inadvertidamente una asignación encadenada.
EDITAR: el código que conduce al error de advertencia de la primera copia.
data['amount'] = data.apply(lambda row: function1(row,date,qty), axis=1)
data['amount'] = data['amount'].astype(float)
def function1(row,date,qty):
try:
if(row['currency'] == 'A'):
result = row[qty]
else:
rate = lookup[lookup['Date']==row[date]][row['currency'] ]
result = float(rate) * float(row[qty])
return result
except ValueError: # generic exception clause
print "The current row causes an exception:"
El objetivo SettingWithCopy
es advertir al usuario que es posible que esté haciendo algo que no actualizará el marco de datos original como cabría esperar.
Aquí data
hay un marco de datos, posiblemente de un solo tipo (o no). Luego estás tomando una referencia a esto, data['amount']
que es una Serie, y actualizándola. Esto probablemente funcione en su caso porque está devolviendo el mismo tipo de datos que existía.
Sin embargo, podría crear una copia que actualice una copia data['amount']
que usted no vería; Entonces te preguntarás por qué no se actualiza.
Pandas devuelve una copia de un objeto en casi todas las llamadas a métodos. Las inplace
operaciones son una operación conveniente que funciona, pero en general no está claro si los datos se están modificando y podrían funcionar en copias.
Mucho más claro hacer esto:
data['amount'] = data["amount"].fillna(data.groupby("num")["amount"].transform("mean"))
data["amount"] = data['amount'].fillna(mean_avg)
Una ventaja más para trabajar con copias. Puedes encadenar operaciones, esto no es posible con inplace
unos.
p.ej
data['amount'] = data['amount'].fillna(mean_avg)*2
Y solo para su información. inplace
las operaciones no son más rápidas ni más eficientes en cuanto a memoria. my2c deberían estar prohibidos. Pero ya es demasiado tarde para esa API.
Por supuesto, puedes desactivar esto:
pd.set_option('chained_assignment',None)
Pandas se ejecuta con todo el conjunto de pruebas con esto configurado raise
(para que sepamos si se está produciendo un encadenamiento), para su información.