apply y map en pandas: diferencias y usos

apply y map en pandas transforman datos, pero trabajan en niveles distintos. Elegir bien mejora la legibilidad y evita ejecutar Python fila por fila cuando existe una operación vectorizada más rápida.
La regla inicial es sencilla: Series.map transforma cada valor de una Serie; DataFrame.apply ejecuta una función por columna o por fila. Para todos los elementos de un DataFrame, las versiones modernas de pandas también ofrecen DataFrame.map.
Series.map para sustituir o transformar valores
import pandas as pd
df = pd.DataFrame({
"estado": ["P", "E", "C", "P"],
"importe": [100, 80, 50, 120],
})
etiquetas = {
"P": "Pendiente",
"E": "Enviado",
"C": "Cancelado",
}
df["estado_nombre"] = df["estado"].map(etiquetas)
Los códigos no presentes en el diccionario producen NaN. Si quieres conservar el original:
mapeado = df["estado"].map(etiquetas)
df["estado_nombre"] = mapeado.fillna(df["estado"])
No ocultes códigos desconocidos sin registrarlos; pueden indicar una nueva categoría o un error de calidad.
map con una función
df["importe_con_iva"] = df["importe"].map(lambda x: x * 1.16)
Funciona, pero una operación vectorizada es más directa:
df["importe_con_iva"] = df["importe"] * 1.16
Antes de usar una función Python por elemento, busca operaciones aritméticas, de texto con .str, de fecha con .dt o métodos nativos.
DataFrame.apply por columna
resumen = df[["importe", "importe_con_iva"]].apply(
["min", "max", "mean"]
)
Con axis=0, el valor predeterminado, la función recibe cada columna. Es útil cuando la operación trabaja con una Serie completa.
apply por fila
def clasificar(fila):
if fila["estado"] == "C":
return "Sin ingreso"
if fila["importe"] >= 100:
return "Prioritario"
return "Normal"
df["segmento"] = df.apply(clasificar, axis=1)
Es expresivo, pero suele ser lento en tablas grandes porque crea y procesa una Serie por fila. Una alternativa vectorizada:
import numpy as np
df["segmento"] = np.select(
[
df["estado"].eq("C"),
df["importe"].ge(100),
],
[
"Sin ingreso",
"Prioritario",
],
default="Normal",
)
La guía de NumPy explica por qué operar sobre arrays evita gran parte de la sobrecarga de bucles Python.
DataFrame.map elemento a elemento
texto = df[["estado", "segmento"]].map(
lambda valor: valor.strip() if isinstance(valor, str) else valor
)
En versiones anteriores se utilizaba DataFrame.applymap; consulta la documentación de la versión instalada antes de migrar. Para una sola columna, Series.map comunica mejor la intención.
apply, map, transform y agg
| Necesidad | Opción |
|---|---|
| Transformar valores de una Serie | Series.map |
| Aplicar función por columna o fila | DataFrame.apply |
| Operar sobre cada celda del DataFrame | DataFrame.map |
| Devolver resultado alineado con el grupo | transform |
| Reducir grupos a resúmenes | agg |
Después de GroupBy, transform conserva el índice:
df["media_estado"] = (
df.groupby("estado")["importe"].transform("mean")
)
agg reduciría cada grupo a una fila.
Medir antes de optimizar
%timeit df["importe"] * 1.16
%timeit df["importe"].map(lambda x: x * 1.16)
El tamaño, el tipo y la función cambian el resultado. Usa datos representativos y verifica equivalencia, no solo tiempo.
Nulos y tipos
Decide cómo debe comportarse la función con pd.NA, NaN o None. Una función que espera texto puede fallar. Los métodos nativos suelen manejar tipos y ausencias de forma más consistente; consulta valores nulos en pandas.
Errores frecuentes
- Usar
axis=1para aritmética simple. - Elegir apply por costumbre sin buscar operación vectorizada.
- Perder códigos no incluidos en un diccionario de map.
- Devolver listas de longitudes diferentes.
- Mezclar tipos en una columna.
- Suponer que “una línea” significa “más rápido”.
- Optimizar sin una prueba de rendimiento.
Prefiere la expresión que haga visible el nivel de la transformación. El rendimiento suele mejorar como consecuencia de trabajar con columnas, no con filas aisladas.
Preguntas frecuentes
¿Cuál es la diferencia entre apply y map en pandas?
Series.map transforma valores individuales; DataFrame.apply entrega una columna o fila completa a la función.
¿apply con axis=1 es lento?
Puede serlo en tablas grandes porque ejecuta lógica Python por fila. Compara con operaciones vectorizadas.
¿Qué pasa si map no encuentra una clave?
Al mapear con diccionario, el resultado suele ser NaN. Audita códigos desconocidos antes de rellenarlos.
¿Qué reemplaza a applymap?
En pandas moderno, DataFrame.map realiza transformaciones elemento a elemento. Revisa la versión instalada.
¿Cuándo uso transform?
Cuando la operación por grupo debe devolver un resultado alineado con cada fila original.
¿Una lambda siempre es más lenta?
No siempre de forma relevante, pero suele perder las optimizaciones de operaciones nativas. Mide con datos reales.

Deja una respuesta