Skip to content

Ventana móvil en Pandas: Rolling, Expanding y EWM

Updated on

Las medias móviles y las señales suavizadas son fundamentales en el análisis de series temporales, pero muchos equipos tienen problemas con la alineación de ventanas, los valores faltantes y los bucles lentos en Python.

  • Problema: Calcular estadísticas móviles “a mano” es propenso a errores y suele quedar desalineado con las marcas de tiempo.
  • Agitación: Los bucles y los desplazamientos ad hoc generan errores de desfase (off‑by‑one), huecos en los primeros periodos y notebooks lentos.
  • Solución: Usa rolling, expanding y ewm con las definiciones de ventana adecuadas (min_periods, ventanas basadas en tiempo, center, adjust) para obtener resultados correctos, rápidos y vectorizados.

Want an AI agent that understands your pandas notebooks and rolling-window features?

RunCell is a JupyterLab AI agent that can read your code, analyze DataFrames, understand notebook context, debug errors, and even generate & execute code for you. It works directly inside JupyterLab—no switching windows or copy-pasting.

👉 Try RunCell: runcell.dev (opens in a new tab)


Referencia rápida

Tipo de ventanaMejor usoParámetros clave
rollingMedias móviles, volatilidad, funciones personalizadas de ventanawindow=3 (o "7D"), min_periods, center, win_type, on
expandingEstadísticas acumuladas desde el iniciomin_periods
ewmSuavizado con decaimiento exponencial o métricas ponderadasspan, alpha, halflife, adjust, times

Datos de ejemplo

import pandas as pd
 
dates = pd.date_range("2024-01-01", periods=8, freq="D")
sales = pd.DataFrame({"date": dates, "revenue": [10, 12, 9, 14, 15, 13, 11, 16]})
sales = sales.set_index("date")

Ventanas móviles (fijas y basadas en tiempo)

Ventanas de tamaño fijo

sales["rev_ma3"] = (
    sales["revenue"]
    .rolling(window=3, min_periods=2)
    .mean()
)
  • min_periods controla cuándo empiezan a aparecer resultados; las filas tempranas permanecen como NaN hasta que se cumple el mínimo de observaciones.
  • center=True alinea la estadística en el centro de la ventana (muy útil para gráficos).

Ventanas basadas en tiempo sobre un índice datetime o columna on=

sales_reset = sales.reset_index()
sales_reset["rev_7d_mean"] = (
    sales_reset.rolling("7D", on="date")["revenue"].mean()
)
  • Usa cadenas de duración ("7D", "48H") para muestreo irregular; pandas selecciona las filas dentro del horizonte de retrospectiva en vez de un conteo fijo.
  • Para controlar la inclusión de bordes, ajusta closed="left" o "right" según lo necesites.

Funciones de ventana personalizadas

sales["rev_range"] = (
    sales["revenue"].rolling(4).apply(lambda x: x.max() - x.min(), raw=True)
)

Configura raw=True para trabajar con arrays de NumPy dentro de apply y ganar velocidad.


Ventanas expansivas (acumulativas)

sales["rev_cum_mean"] = sales["revenue"].expanding(min_periods=2).mean()
  • Usa expanding cuando cada observación deba ver todo lo ocurrido hasta ese punto (media móvil acumulada, ratios acumulados).
  • Combínalo con shift() para comparar el valor más reciente contra el promedio histórico.

Ventanas con ponderación exponencial

sales["rev_ewm_span4"] = sales["revenue"].ewm(span=4, adjust=False).mean()
  • adjust=False utiliza una fórmula recursiva que imita el suavizado típico en paneles analíticos.
  • halflife ofrece un decaimiento intuitivo: ewm(halflife=3) reduce a la mitad el peso cada 3 periodos.
  • Para marcas de tiempo irregulares, pasa times="date" (o establece el índice) para ponderar por los deltas de tiempo reales en lugar de por el número de filas.

Cómo elegir la ventana adecuada (chuleta)

ObjetivoMétodo recomendadoNotas
Suavizar ruido a corto plazorolling con window pequeño y center=TrueFunciona sobre columnas numéricas; mantén min_periods ≥ 1 para ver datos desde el inicio
Totales o promedios acumulados desde el inicioexpandingSin ventana fija; ideal para KPIs que se acumulan
Hacer que las observaciones antiguas pesen menosewm(span=...)Mejor que ventanas rolling grandes para señales tipo momentum
Tiempos irregularesrolling("7D", on="date") o ewm(..., times="date") basados en tiempoEvita sesgos por días con muestreo más denso
Generación de featuresrolling().agg(["mean","std","min","max"])La multi‑agregación genera rápidamente conjuntos ordenados de features

Consejos de rendimiento y corrección

  • Mantén las columnas de fechas como datetime64[ns] y define un índice cuando trabajes intensamente con ventanas basadas en tiempo.
  • Prioriza las agregaciones integradas (mean, std, sum, count) sobre apply en Python para ganar velocidad.
  • Evita el sesgo con información futura: aplica shift() antes de rolling si estás construyendo features para aprendizaje supervisado.
  • Combina con resample para normalizar la frecuencia antes de usar ventanas móviles si los datos de origen son irregulares.

rolling, expanding y las ventanas exponenciales cubren la mayoría de las necesidades de suavizado e ingeniería de features sin usar bucles. Combínalos con pandas-to-datetime y pandas-resample para obtener ejes de tiempo limpios, y así conseguir métricas rápidas y fiables listas para gráficos o modelos.