Comprensión in situ = Verdadero


104

En la pandasbiblioteca muchas veces hay una opción para cambiar el objeto en su lugar, 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 cuándo inplace=Truese pasa frente a cuándo inplace=False.

¿Todas las operaciones están modificando selfcuándo inplace=True? ¿Y cuándo inplace=Falsese crea un nuevo objeto inmediatamente como new_df = selfy luego new_dfse devuelve?


13
Sí, inplace=Truedevuelve None inplace=Falsedevuelve una copia del objeto con la operación realizada. Los documentos son bastante claros al respecto, ¿hay algo que sea confuso con una parte específica? SpeficallyIf True, do operation inplace and return None.
EdChum

Estoy subclasificando el objeto DataFrame y con una operación como fusionar no parece posible hacerlo en el lugar ... self = self.merge(new_df, how='left', on='column2' No estoy seguro de que sea posible reasignarme a mí mismo
Aran Freel

1
Tiene razón en que DataFrame.merge no tiene inplaceargumentos. Devuelve un DataFrame, por lo que no hay problemas para reasignar.
JAV

¿Alguien puede también destacar las ventajas de usarlo en términos de consumo de recursos?
markroxor

2
@markroxor Realmente no hay muchos. En algunos casos, la inplaceacción puede ser un poco más rápida, ya que en realidad no tiene que devolver una copia del resultado. Pero eso es todo. Hay muchas más razones para no usarlo.
cs95

Respuestas:


96

Cuando inplace=Truese pasa, los datos se renombran en su lugar (no devuelven nada), por lo que usaría:

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ía:

df = df.an_operation(inplace=False) 

¿Estaría en lo cierto al pensar que inplacees solo una opción para los métodos que alteran los datos existentes, pero no para los métodos que 'remodelan' los datos? Por ejemplo, puedo .set_index (inplace = True) ya que esto aplica valores al índice existente, pero no puedo .reindex (inplace = True) porque esto podría crear filas adicionales en el DataFrame que no existían en la matriz anterior ?
ac24

4
El método .dropna()acepta inplace=Truey definitivamente puede remodelar el marco de datos, así que no.
jorijnsmit

3
Tienes que tener cuidado aquí. @ ac24 tiene más o menos razón. Si bien dropnadevuelve un marco de datos de forma diferente, en realidad no cambia la forma de los datos subyacentes, simplemente devuelve una máscara sobre él (cuándo inplace=False), lo que puede llevar a lo temido SettingWithCopyWarning. Solo cuando no haya más referencias a la antigua matriz de valores, los pandas cambiarán de forma de acuerdo con la máscara. Una mejor regla general es: inplaceestá disponible cuando la operación no requiere la asignación de un nuevo ndarray de valores de respaldo.
BallpointBen

46

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

5
Hola @Nabin, Eso es demasiado claro para cualquiera que trabaje en Pandas y Numpy :-)
Vetrivel PS

44

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

TLDR; Sí, así es.

  • inplace, al contrario de lo que implica el nombre, a menudo no impide la creación de copias y (casi) nunca ofrece beneficios de rendimiento.
  • inplace no funciona con el método de encadenamiento
  • inplace es un error común para los principiantes, por lo que eliminar esta opción simplificará la API

No recomiendo configurar este parámetro, ya que tiene poco propósito . Vea este problema de GitHub que propone que el inplaceargumento sea 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, hay absolutamente ninguna ventajas de rendimiento a utilizar inplace=True. Tanto la versión en el lugar como fuera de lugar crean una copia de los datos de todos modos , y la versión en el lugar 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 con inplace=True puede o no funcionar . 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 . Contrasta 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 de set_axisse modificó recientemente de modo que inplaceel valor predeterminado se cambió de Verdadero a Falso. Consulte GH27600 . ¡Buen trabajo, desarrolladores!


Seguro inplace=Trueque no funciona con el encadenamiento, etc., pero eso es obvio si entiendes lo que está haciendo conceptualmente. Personalmente, lo encuentro un poco más limpio para evitar la asignación. ¿También estaría a favor de eliminar list.sortetc. de la biblioteca estándar?
Chris_Rands

4
No creo que sea una comparación justa. Existen algunos beneficios obvios de usar list.sort versus sorted. Lo mismo ocurre con las otras funciones in situ. No hay ningún beneficio real aquí, el encadenamiento de métodos es mucho más común en pandas y hay planes para la desaprobación de este argumento de todos modos.
cs95

También lo encuentro un poco más limpio para evitar la asignación: también, por ejemplo, python list.append()también está en su lugar, mientras que pandas df.append no lo está (y ni siquiera admite en su lugar), lo que me irrita muchísimo. Es por eso que me gustaría saber, solo para entender cuáles son los beneficios reales: ¿cuáles son los beneficios obvios de usar list.sort versus sorted, además de evitar la asignación? De lo contrario, creo que hay un beneficio real aquí: poder evitar la asignación, donde personalmente lo encuentro más legible.
sdbbs

1
@sdbbs se list.append()agrega a una lista existente. df.appendhace una copia de sus datos (no importa si tiene 5 filas o 5 millones), luego agrega una nueva fila a su copia y luego la devuelve. ¿Qué crees que tiene más sentido? En cuanto a df.append, EVITE TODO LO POSIBLE . No creo que sea un buen ejemplo para defender inplace = True, ni siquiera creo que esa función tenga un lugar en la API.
cs95

6

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 sobre él

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

4. ... elimina la copia.

Como puede leer en el resto de mi respuesta más abajo, todavía podemos tener una buena razón para usar este parámetro, es decir inplace operations, el , pero deberíamos 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 de este posible problema)

2. Conflicto con el encadenamiento de métodos


Entonces, ¿incluso hay un caso en el que deberíamos usarlo todavía?

Definitivamente si. Si usamos pandas o cualquier herramienta para manejar un gran conjunto de datos, podemos enfrentar fácilmente la situación, donde 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 más difícil de interpretar y depurar también) y consume menos memoria ya que los métodos encadenados funcionan con los valores devueltos del otro método, lo que resulta en una sola copia de los datos de entrada. Podemos ver claramente que tendremos 2 x consumo de memoria de datos original después de estas operaciones.

O podemos usar el inplaceparámetro (aunque más difícil de interpretar y depurar también) 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 , que si alguien siempre trabajó con grandes conjuntos de datos sabe exactamente que puede ser un gran beneficio.


Conclusión final:

Evite el uso de inplaceparámetros a menos que no trabaje con datos enormes y sea consciente de sus posibles problemas en caso de seguir usándolos.


2

Guárdalo en la misma variable

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

Guárdelo 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)

FYI: por defecto inplace = False


1

Cuando intentamos realizar cambios en un marco de datos de Pandas usando una función, usamos 'inplace = True' si queremos confirmar los cambios en el marco de datos. Por lo tanto, la primera línea del código siguiente cambia el nombre de la primera columna en 'df' a 'Calificaciones'. Necesitamos llamar a la base de datos si queremos ver la base de datos resultante.

df.rename(columns={0: 'Grades'}, inplace=True)
df

Usamos 'inplace = False' (este es también el valor predeterminado) cuando no queremos confirmar los cambios, sino simplemente imprimir la base de datos resultante. Entonces, en efecto, se imprime una copia de la base de datos original con los cambios confirmados sin alterar la base de datos original.

Para ser más claro, los siguientes códigos hacen lo mismo:

#Code 1
df.rename(columns={0: 'Grades'}, inplace=True)
#Code 2
df=df.rename(columns={0: 'Grades'}, inplace=False}

0

inplace=True se utiliza dependiendo de si desea realizar cambios en el df original o no.

df.drop_duplicates()

solo hará una vista de los valores eliminados, pero no realizará ningún cambio en df

df.drop_duplicates(inplace  = True)

eliminará valores y realizará cambios en df.

Espero que esto ayude.:)


0

inplace=Truehace que la función sea impura. Cambia el marco de datos original y devuelve Ninguno. En ese caso, rompe la cadena DSL. Debido a que la mayoría de las funciones de marco de datos devuelven un nuevo marco de datos, puede utilizar el DSL cómodamente. Me gusta

df.sort_values().rename().to_csv()

La llamada a la función inplace=Truedevuelve None y la cadena DSL está rota. Por ejemplo

df.sort_values(inplace=True).rename().to_csv()

arrojará NoneType object has no attribute 'rename'

Algo similar con la ordenación y ordenación incorporadas de Python. lst.sort()devuelve Noneysorted(lst) devuelve una nueva lista.

Generalmente, no lo use a inplace=Truemenos que tenga una razón específica para hacerlo. Cuando tenga que escribir un código de reasignación como df = df.sort_values(), intente adjuntar la llamada a la función en la cadena DSL, por ejemplo

df = pd.read_csv().sort_values()...

proporcionar un código de trabajo exacto con el formato adecuado realmente ayudará a los usuarios a comprender su respuesta más rápido. Solicitándole que haga lo mismo. No soy un experto en pandas, así que no puedo reformatear tu respuesta, pero es muy recomendable,
Anand Vaidya

0

En cuanto a mi experiencia en pandas me gustaría responder.

El argumento 'inplace = True' significa que el marco de datos tiene que hacer cambios permanentes, por ejemplo.

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

cambia el mismo marco de datos (ya que estos pandas encuentran entradas NaN en el índice y las sueltan). Si lo intentamos

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

pandas muestra el marco de datos con los cambios que hacemos, pero no modificará el marco de datos original 'df'.


0

Si no usa inplace = True o usa inplace = False, básicamente obtiene una copia.

Entonces, por ejemplo:

testdf.sort_values(inplace=True, by='volume', ascending=False)

alterará la estructura con los datos ordenados en orden descendente.

entonces:

testdf2 = testdf.sort_values( by='volume', ascending=True)

hará que testdf2 sea una copia. los valores serán todos iguales, pero la ordenación se invertirá y tendrá un objeto independiente.

luego, dada otra columna, di LongMA y lo haces:

testdf2.LongMA = testdf2.LongMA -1

la columna LongMA en testdf tendrá los valores originales y testdf2 tendrá los valores desacreditados.

Es importante realizar un seguimiento de la diferencia a medida que crece la cadena de cálculos y las copias de los marcos de datos tienen su propio ciclo de vida.


0

Sí, en Pandas tenemos muchas funciones tiene el parámetro inplacepero por defecto está asignado False.

Entonces, cuando lo hace df.dropna(axis='index', how='all', inplace=False), piensa que no desea cambiar el original DataFrame, por lo tanto, crea una nueva copia para usted con los cambios requeridos.

Pero, cuando cambia el inplaceparámetro aTrue

Entonces es equivalente a decir explícitamente que no quiero una nueva copia del, en DataFramelugar de hacer los cambios en el dadoDataFrame

Esto obliga al intérprete de Python a no crear un nuevoDataFrame

Pero también puede evitar el uso del inplaceparámetro reasignando el resultado al DataFrame original

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.