Comprender inplace=True en pandas

Resuelto Aran Freel asked hace 7 años • 11 respuestas

En la pandasbiblioteca muchas veces hay una opción para cambiar el objeto in situ, como con la siguiente declaración...

df.dropna(axis='index', how='all', inplace=True)

Tengo curiosidad por saber qué se devuelve y cómo se maneja el objeto cuando inplace=Truese pasa y cuando inplace=False.

¿Todas las operaciones se modifican selfcuando inplace=True? ¿Y cuándo inplace=Falsese crea inmediatamente un nuevo objeto new_df = selfy luego new_dfse devuelve?


Si está intentando cerrar una pregunta que alguien debería usar inplace=Truey no lo ha hecho, considere que el método replace() no funciona en Pandas DataFrame .

Aran Freel avatar May 10 '17 20:05 Aran Freel
Aceptado

Cuando inplace=Truese pasa, se cambia el nombre de los datos en su lugar (no devuelve nada), por lo que usarías:

df.an_operation(inplace=True)

Cuando inplace=Falsese pasa (este es el valor predeterminado, por lo que no es necesario), realiza la operación y devuelve una copia del objeto, por lo que usarías:

df = df.an_operation(inplace=False) 
Ed Harrod avatar Aug 24 '2017 08:08 Ed Harrod

En los pandas, ¿inplace = True se considera dañino o no?

TLDR; Sí, así es.

  • inplace, al contrario de lo que sugiere el nombre, a menudo no impide la creación de copias y (casi) nunca ofrece ningún beneficio de rendimiento.
  • inplaceno funciona con encadenamiento de métodos
  • inplacepuede provocar SettingWithCopyWarningsi se usa en una columna DataFrame y puede impedir que se realice la operación, lo que genera errores difíciles de depurar en el código.

Los puntos débiles anteriores son errores comunes para los principiantes, por lo que eliminar esta opción simplificará la API.


No recomiendo configurar este parámetro ya que sirve de poco . Vea este problema de GitHub que propone que el inplaceargumento quede obsoleto en toda la API.

Es un error común pensar que el uso inplace=Trueconducirá a un código más eficiente u optimizado. En realidad, el uso de inplace=True. Tanto la versión local como la fuera de lugar crean una copia de los datos de todos modos , y la versión local asigna automáticamente la copia.

inplace=TrueEs un error común para los principiantes. Por ejemplo, puede desencadenarSettingWithCopyWarning :

df = pd.DataFrame({'a': [3, 2, 1], 'b': ['x', 'y', 'z']})

df2 = df[df['a'] > 1]
df2['b'].replace({'x': 'abc'}, inplace=True)
# SettingWithCopyWarning: 
# A value is trying to be set on a copy of a slice from a DataFrame

Llamar a una función en una columna DataFrame inplace=True puede funcionar o no . Esto es especialmente cierto cuando se trata de indexación encadenada.

Como si los problemas descritos anteriormente no fueran suficientes, inplace=Truetambién dificulta el encadenamiento de métodos . Contraste el funcionamiento de

result = df.some_function1().reset_index().some_function2()

Opuesto a

temp = df.some_function1()
temp.reset_index(inplace=True)
result = temp.some_function2()

El primero se presta a una mejor organización y legibilidad del código.


Otra afirmación de respaldo es que la API set_axisse cambió recientemente de modo que inplaceel valor predeterminado pasó de Verdadero a Falso. Ver GH27600 . ¡Buen trabajo desarrolladores!

cs95 avatar Dec 09 '2019 03:12 cs95

La forma en que lo uso es

# Have to assign back to dataframe (because it is a new copy)
df = df.some_operation(inplace=False) 

O

# No need to assign back to dataframe (because it is on the same copy)
df.some_operation(inplace=True)

CONCLUSIÓN:

 if inplace is False
      Assign to a new variable;
 else
      No need to assign
Nabin avatar Mar 04 '2018 02:03 Nabin

El inplaceparámetro:

df.dropna(axis='index', how='all', inplace=True)

en Pandasy en general significa:

1. Pandas crea una copia de los datos originales.

2. ... hace algunos cálculos al respecto

3. ... asigna los resultados a los datos originales.

4. ... elimina la copia.

Como puede leer en el resto de mis respuestas más abajo, aún podemos tener buenas razones para usar este parámetro, es decir inplace operations, , pero debemos evitarlo si podemos, ya que genera más problemas, como:

1. Su código será más difícil de depurar (en realidad, SettingwithCopyWarning significa advertirle sobre este posible problema)

2. Conflicto con el encadenamiento de métodos


Entonces, ¿hay algún caso en el que deberíamos usarlo todavía?

Definitivamente sí. Si utilizamos pandas o cualquier herramienta para manejar un gran conjunto de datos, podemos enfrentar fácilmente la situación en la que algunos grandes datos pueden consumir toda nuestra memoria. Para evitar este efecto no deseado podemos utilizar algunas técnicas como el encadenamiento de métodos :

(
    wine.rename(columns={"color_intensity": "ci"})
    .assign(color_filter=lambda x: np.where((x.hue > 1) & (x.ci > 7), 1, 0))
    .query("alcohol > 14 and color_filter == 1")
    .sort_values("alcohol", ascending=False)
    .reset_index(drop=True)
    .loc[:, ["alcohol", "ci", "hue"]]
)

lo que hace que nuestro código sea más compacto (aunque también más difícil de interpretar y depurar) y consume menos memoria ya que los métodos encadenados funcionan con los valores devueltos por el otro método, lo que da como resultado solo una copia de los datos de entrada. Podemos ver claramente que tendremos 2 veces el consumo de memoria de datos original después de estas operaciones.

O podemos usar inplaceun parámetro (aunque también es más difícil de interpretar y depurar), nuestro consumo de memoria será 2 x datos originales , pero nuestro consumo de memoria después de esta operación sigue siendo 1 x datos originales , lo que si alguien siempre ha trabajado con grandes conjuntos de datos sabe exactamente que puede ser un gran beneficio.


Conclusión final:

Evite el uso inplacede parámetros a menos que no trabaje con una gran cantidad de datos y sea consciente de sus posibles problemas en caso de seguir utilizándolos.

Geeocode avatar Dec 14 '2019 13:12 Geeocode

Guárdalo en la misma variable.

data["column01"].where(data["column01"]< 5, inplace=True)

Guárdalo en una variable separada

data["column02"] = data["column01"].where(data["column1"]< 5)

Pero siempre puedes sobrescribir la variable.

data["column01"] = data["column01"].where(data["column1"]< 5)

Para su información: en defaultinplace = False

hyukkyulee avatar Sep 13 '2018 18:09 hyukkyulee