1/1. Un DataFrame de pandas se modifica dentro de una función

Este post cubre un comportamiento común de pandas: los DataFrames son mutables, así que una función puede modificar el objeto del caller aunque no lo retorne. Está documentado en la guía de copy vs view y en la API de DataFrame.

Descargas al final: ir a Descargas.

En pocas palabras

  • Un DataFrame es mutable; las operaciones in‑place modifican el original.
  • El bug parece “no retornó nada, pero cambió”.
  • Solución: copiar, retornar o hacer explícita la mutación.

Repro mínima (ejecutable)

Ejecuta esto como script. La función modifica raw, aunque ignores el retorno.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import pandas as pd

def clean_prices(df):
    df["price"] = df["price"].astype(float)
    df.dropna(inplace=True)
    return df

raw = pd.DataFrame({"price": ["10", None, "20"]})
_ = clean_prices(raw)

print(raw)

Salida esperada:

1
2
3
  price
0  10.0
2  20.0

Por qué pasa

DataFrame es mutable. Al pasarlo a una función pasas una referencia. Cualquier operación in‑place (dropna(inplace=True), asignación a una columna, rename(inplace=True)) afecta el mismo objeto en memoria. La documentación de pandas lo advierte en copy vs view.

Patrones más seguros (elige uno)

1) Retornar un objeto nuevo

Haz una copia y retorna el nuevo DataFrame.

1
2
3
4
5
def clean_prices(df):
    out = df.copy()
    out["price"] = out["price"].astype(float)
    out = out.dropna()
    return out

2) Mutar a propósito

Si quieres in‑place, hazlo explícito.

1
2
3
4
def clean_prices_inplace(df):
    df["price"] = df["price"].astype(float)
    df.dropna(inplace=True)
    return None

3) Haz visible la intención

El nombre debe avisar al caller.

1
2
def clean_prices_inplace(df):
    ...

Checklist práctico

  • Evita inplace=True salvo que realmente quieras mutar.
  • Si mutas, nombra *_inplace.
  • Si retornas, copia primero.

Descargas