Pandas & NumPy Academy · Lección

Ventanas móviles

Calcule medias, sumas y desviaciones estándar móviles sobre un número fijo de filas con rolling(n).mean() y métodos relacionados.

Lección 1 de 413 pasos

Ventanas móviles es una lección gratuita de Pandas & NumPy Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Pandas & NumPy Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Pandas & NumPy Academy incluye 4 lecciones en total.

¿Qué son las ventanas móviles?

Una ventana móvil (también llamada ventana deslizante) calcula una estadística sobre una ventana de tamaño fijo formada por filas consecutivas, mientras avanza una fila cada vez. Por ejemplo, una media móvil de 7 días sustituye el valor de cada día por la media de ese día y de los 6 días anteriores. Las ventanas móviles son la base de las medias móviles en finanzas, el suavizado de datos de sensores ruidosos y el cálculo de métricas acumuladas en paneles de negocio.

import pandas as pd
import numpy as np

# Simple example: 3-day rolling mean
data = pd.Series([10, 12, 15, 11, 9, 13, 16, 14, 12, 18],
                 index=pd.date_range('2024-01-01', periods=10))

rolling_mean = data.rolling(window=3).mean()
print('Original:')
print(data.values)
print('\n3-day rolling mean:')
print(rolling_mean.values.round(2))

El método rolling() y el parámetro window

Series.rolling(window=n) devuelve un objeto Rolling. El parámetro window indica el tamaño de la ventana deslizante en número de filas (para ventanas enteras) o un desplazamiento temporal como '7D' (para Series indexadas por tiempo). Después de crear el objeto rolling, encadene cualquier método de agregación: .mean(), .sum(), .std(), .min(), .max() o incluso .apply(func). Las primeras window-1 filas siempre serán NaN porque no hay suficientes filas anteriores para completar la ventana.

import pandas as pd
import numpy as np

prices = pd.Series(
    [100, 102, 98, 105, 110, 108, 115, 112, 120, 118],
    index=pd.date_range('2024-01-01', periods=10),
    name='price'
)

df = pd.DataFrame({'price': prices})
df['MA3'] = df['price'].rolling(3).mean()
df['MA7'] = df['price'].rolling(7).mean()
df['std3'] = df['price'].rolling(3).std()
print(df.round(2))

Parámetro min_periods

De forma predeterminada, rolling(n) requiere exactamente n valores que no sean NaN en la ventana antes de calcular un resultado. El parámetro min_periods reduce este requisito; por ejemplo, rolling(7, min_periods=3) calcula la media en cuanto hay al menos 3 valores disponibles, por lo que produce valores que no son NaN antes en la Series. Esto resulta útil cuando desea obtener medias móviles al principio de una serie temporal en lugar de NaN en las primeras n-1 filas.

import pandas as pd
import numpy as np

prices = pd.Series([100, 102, 98, 105, 110, 108, 115],
                   index=pd.date_range('2024-01-01', periods=7))

# Default: first 6 rows are NaN
ma7_default = prices.rolling(7).mean()

# min_periods=3: compute mean once 3 values available
ma7_minperiods = prices.rolling(7, min_periods=3).mean()

df = pd.DataFrame({
    'price': prices,
    'MA7_default': ma7_default,
    'MA7_min3': ma7_minperiods
})
print(df.round(2))

Suma móvil para totales acumulados

rolling(n).sum() calcula el total de las últimas n filas en cada posición. Una suma móvil de 30 días de las ventas diarias proporciona los ingresos mensuales acumulados de cada día, lo que resulta más informativo que un total mensual estático porque se actualiza diariamente. Las sumas móviles se utilizan habitualmente en análisis minoristas (ventas de los últimos 30 días), análisis web (usuarios activos de los últimos 7 días) y finanzas (volumen acumulado de los últimos n periodos).

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=60)
daily_sales = pd.Series(np.random.randint(100, 500, 60), index=dates, name='daily_sales')

df = pd.DataFrame({'daily_sales': daily_sales})
df['trailing_7d'] = df['daily_sales'].rolling(7).sum()
df['trailing_30d'] = df['daily_sales'].rolling(30).sum()

print(df.tail(10).round(0))

Desviación estándar móvil para medir la volatilidad

En finanzas, la volatilidad se mide como la desviación estándar móvil de los rendimientos diarios. Una desviación estándar móvil alta significa que los precios fluctúan mucho; una baja indica precios estables. Esta métrica se utiliza en los cálculos de riesgo para la valoración de opciones y la gestión de carteras. La fórmula es la siguiente: calcule los rendimientos logarítmicos diarios con np.log(price/price.shift(1)) y, después, aplique rolling(window).std().

import pandas as pd
import numpy as np

np.random.seed(0)
prices = pd.Series(
    100 * np.exp(np.cumsum(np.random.normal(0.001, 0.02, 120))),
    index=pd.date_range('2024-01-01', periods=120)
)

# Daily log returns
log_returns = np.log(prices / prices.shift(1))

# 20-day rolling volatility (annualised)
volatility = log_returns.rolling(20).std() * np.sqrt(252)

print('Last 5 rows of daily volatility:')
print(volatility.tail(5).round(4))

Ventanas móviles basadas en el tiempo

En lugar de especificar un número fijo de filas, puede indicar un desplazamiento temporal como ventana: rolling('7D') significa «los últimos 7 días naturales con datos». Esto gestiona correctamente las series temporales irregulares (fines de semana y festivos ausentes): una ventana basada en el número de filas incluiría una cantidad distinta de tiempo natural según los intervalos, mientras que una ventana basada en un desplazamiento temporal siempre abarca exactamente 7 días de datos. La Series debe tener un DatetimeIndex para usar ventanas basadas en el tiempo.

import pandas as pd
import numpy as np

# Business-day index (no weekends)
biz_dates = pd.bdate_range('2024-01-01', periods=15)
sales = pd.Series(np.random.randint(100, 300, 15), index=biz_dates)

# 7-calendar-day window (variable row count near weekends)
df = pd.DataFrame({'sales': sales})
df['rolling_7d'] = sales.rolling('7D').mean()

print(df.round(1))

Rolling apply para funciones personalizadas

rolling(n).apply(func) pasa cada ventana como un array de NumPy a su función personalizada. Esto permite realizar cualquier cálculo móvil que no esté cubierto por las agregaciones integradas, como la desviación absoluta mediana móvil, la asimetría móvil o el primer cuartil móvil. La función debe aceptar un array unidimensional y devolver un escalar. Nota: apply es más lento que los métodos integrados porque no puede vectorizarse.

import pandas as pd
import numpy as np

prices = pd.Series(
    [100, 102, 98, 105, 110, 95, 115, 112, 120, 108],
    index=pd.date_range('2024-01-01', periods=10)
)

# Rolling range (max - min) over a 5-day window
def rolling_range(arr):
    return arr.max() - arr.min()

df = pd.DataFrame({'price': prices})
df['5d_range'] = prices.rolling(5).apply(rolling_range, raw=True)
print(df.round(2))

Rolling en las columnas de un DataFrame

Puede aplicar rolling().mean() directamente a un DataFrame para calcular estadísticas móviles de todas las columnas numéricas simultáneamente. Cada columna obtiene su propia ventana móvil, calculada de forma independiente. Esto resulta útil para calcular medias móviles de varios precios de acciones o de varias líneas de ventas de productos en una sola operación, sin recorrer las columnas.

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10)
df = pd.DataFrame({
    'AAPL': 100 + np.cumsum(np.random.randn(10)),
    'MSFT': 200 + np.cumsum(np.random.randn(10)),
    'GOOG': 150 + np.cumsum(np.random.randn(10))
}, index=dates)

# 3-day moving average of all three stocks
ma3 = df.rolling(3).mean()
print('3-day MA for all stocks:')
print(ma3.round(2))

Combinar la media móvil con la serie original

Un patrón habitual de visualización consiste en representar la serie temporal sin modificar y su media móvil sobre los mismos ejes. La media móvil revela la tendencia al suavizar el ruido diario, mientras que la serie original muestra la volatilidad. La distancia entre ambas indica cuánto ruido hay. Añadir una media móvil a un DataFrame es tan sencillo como asignar el resultado a una columna nueva.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=60)
sales = pd.Series(
    200 + np.cumsum(np.random.randn(60) * 10),
    index=dates, name='Daily Sales'
)

df = pd.DataFrame({'sales': sales})
df['MA7'] = df['sales'].rolling(7).mean()
df['MA30'] = df['sales'].rolling(30).mean()

df.plot(figsize=(12, 5), title='Sales with 7-day and 30-day Moving Average')
plt.ylabel('Sales')
plt.show()

Ventanas móviles centradas

De forma predeterminada, rolling utiliza una ventana retrospectiva (la fila actual y las n-1 filas anteriores). Establecer center=True crea una ventana centrada en la que la fila actual queda en el medio y se utilizan el mismo número de filas anteriores y posteriores. Las ventanas centradas producen resultados más suaves y son apropiadas para el suavizado offline de datos históricos cuando se conocen los valores futuros. NO son apropiadas para realizar predicciones en tiempo real porque requieren datos futuros.

import pandas as pd
import numpy as np

np.random.seed(0)
data = pd.Series(
    np.sin(np.linspace(0, 4*3.14159, 30)) + np.random.normal(0, 0.3, 30)
)

df = pd.DataFrame({'signal': data})
df['trailing_MA5'] = data.rolling(5).mean()
df['centered_MA5'] = data.rolling(5, center=True).mean()

print('Comparison (first 8 rows):')
print(df.head(8).round(3))

Ventanas móviles para datos agrupados con GroupBy

Puede calcular estadísticas móviles por grupo mediante groupby().rolling(). Por ejemplo, puede calcular los ingresos móviles de 7 días para cada categoría de producto; la ventana se reinicia al comienzo de cada grupo, por lo que los datos de un producto no se mezclan con los de otro. Después de la operación móvil, utilice .reset_index(level=0, drop=True) para eliminar del índice el nivel adicional del grupo y alinear el resultado con el DataFrame original.

import pandas as pd
import numpy as np

np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10)
df = pd.DataFrame({
    'date': list(dates) * 2,
    'product': ['A'] * 10 + ['B'] * 10,
    'sales': np.random.randint(50, 200, 20)
}).sort_values(['product', 'date'])

# 3-day rolling mean per product
df['rolling_mean'] = (df
    .groupby('product')['sales']
    .transform(lambda x: x.rolling(3).mean())
)
print(df.to_string(index=False))

Comprobación rápida

Compruebe su comprensión de las ventanas móviles de esta lección.

Resumen de la lección

En esta lección ha aprendido que rolling(n) crea una ventana deslizante de n filas en la que puede calcular la media, la suma, la desviación estándar, el mínimo, el máximo o funciones personalizadas; min_periods reduce el número mínimo de valores necesarios para calcular un resultado; y center=True crea ventanas centradas para suavizado sin desfase. A continuación exploraremos las ventanas expansivas: estadísticas acumuladas que crecen desde el inicio de la Series.

Gratis para empezar

Aprende Python con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
30
Lecciones
120

Preguntas frecuentes

¿La lección «Ventanas móviles» es gratis?

Sí — el texto completo de «Ventanas móviles» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Pandas & NumPy Academy, actualiza a CoddyKit PRO. El curso de Pandas & NumPy Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Ventanas móviles»?

Calcule medias, sumas y desviaciones estándar móviles sobre un número fijo de filas con rolling(n).mean() y métodos relacionados. Practicas Pandas & NumPy Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Pandas & NumPy Academy?

No se requiere experiencia previa. Pandas & NumPy Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Ventanas móviles»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Pandas & NumPy Academy?

Sí. Cada lección de Pandas & NumPy Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Ventanas móviles
  2. Ventanas expansivas
  3. Media móvil ponderada exponencialmente
  4. Rangos y percentiles dentro de grupos
← Volver a Pandas & NumPy Academy