Analisis Basico de Series Temporales
Datos que Cambian en el TiempoUna serie temporal es una secuencia de datos ordenados cronologicamente: ventas diarias, temperaturas horarias, precios de acciones. Analizar tendencias, estacionalidad y patrones temporales es una habilidad critica para cualquier analista de datos.
Trabajar con Fechas en Pandas
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Crear un rango de fechas
fechas = pd.date_range(start='2023-01-01', end='2025-12-31', freq='D')
print(f"Dias: {len(fechas)}")
print(f"Desde: {fechas[0]}")
print(f"Hasta: {fechas[-1]}")
# Generar serie temporal de ventas
np.random.seed(42)
n = len(fechas)
tendencia = np.linspace(100, 200, n) # Tendencia creciente
estacionalidad = 30 * np.sin(2 * np.pi * np.arange(n) / 365.25) # Ciclo anual
ruido = np.random.normal(0, 15, n)
ventas = tendencia + estacionalidad + ruido
df = pd.DataFrame({'fecha': fechas, 'ventas': ventas})
df = df.set_index('fecha')
print(df.head())
print(f"\nPeriodo: {df.index[0].strftime('%Y-%m-%d')} a {df.index[-1].strftime('%Y-%m-%d')}")
Resampling: Cambiar la Frecuencia
# De diario a semanal
df_semanal = df.resample('W').mean()
print("Ventas promedio semanal:")
print(df_semanal.head())
# De diario a mensual
df_mensual = df.resample('M').agg({
'ventas': ['mean', 'sum', 'std', 'count']
})
df_mensual.columns = ['promedio', 'total', 'desviacion', 'dias']
print("\nResumen mensual:")
print(df_mensual.head())
# De diario a trimestral
df_trimestral = df.resample('Q').sum()
print("\nVentas trimestrales:")
print(df_trimestral.head())
Medias Moviles (Rolling)
Las medias moviles suavizan el ruido y revelan la tendencia subyacente.
# Calcular medias moviles
df['mm_7'] = df['ventas'].rolling(window=7).mean() # 7 dias
df['mm_30'] = df['ventas'].rolling(window=30).mean() # 30 dias
df['mm_90'] = df['ventas'].rolling(window=90).mean() # 90 dias
# Visualizar
fig, ax = plt.subplots(figsize=(14, 6))
ax.plot(df.index, df['ventas'], alpha=0.3, label='Diario')
ax.plot(df.index, df['mm_7'], label='Media 7 dias', linewidth=1)
ax.plot(df.index, df['mm_30'], label='Media 30 dias', linewidth=2)
ax.plot(df.index, df['mm_90'], label='Media 90 dias', linewidth=2)
ax.set_title('Ventas Diarias con Medias Moviles')
ax.set_xlabel('Fecha')
ax.set_ylabel('Ventas')
ax.legend()
plt.tight_layout()
plt.show()
Analisis de Tendencia y Estacionalidad
# Comparar anios
df_pivot = df.copy()
df_pivot['anio'] = df_pivot.index.year
df_pivot['mes'] = df_pivot.index.month
ventas_por_mes = df_pivot.groupby(['anio', 'mes'])['ventas'].mean().reset_index()
ventas_pivot = ventas_por_mes.pivot(index='mes', columns='anio', values='ventas')
fig, ax = plt.subplots(figsize=(10, 6))
ventas_pivot.plot(ax=ax, marker='o')
ax.set_title('Ventas Promedio por Mes y Anio')
ax.set_xlabel('Mes')
ax.set_ylabel('Ventas promedio')
ax.set_xticks(range(1, 13))
ax.set_xticklabels(['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'])
ax.legend(title='Anio')
plt.tight_layout()
plt.show()
Crecimiento year-over-year
# Ventas mensuales totales
df_monthly = df.resample('M')['ventas'].sum()
# Cambio porcentual mes a mes
cambio_mensual = df_monthly.pct_change() * 100
# Year-over-year (comparar con mismo mes del anio anterior)
yoy = df_monthly.pct_change(periods=12) * 100
resumen = pd.DataFrame({
'ventas': df_monthly,
'cambio_mensual_%': cambio_mensual,
'yoy_%': yoy
})
print("Crecimiento Year-over-Year:")
print(resumen.tail(12).round(1))
Descomposicion de Series Temporales
from statsmodels.tsa.seasonal import seasonal_decompose
# Descomponer en tendencia, estacionalidad y residuos
resultado = seasonal_decompose(df['ventas'], model='additive', period=365)
fig, axes = plt.subplots(4, 1, figsize=(14, 10))
resultado.observed.plot(ax=axes[0], title='Datos Observados')
resultado.trend.plot(ax=axes[1], title='Tendencia')
resultado.seasonal.plot(ax=axes[2], title='Estacionalidad')
resultado.resid.plot(ax=axes[3], title='Residuos')
plt.tight_layout()
plt.show()
Video Recomendado
Series Temporales con Python y Pandas
Ejercicio Practico
Crea un notebook 15_series_temporales.ipynb:
- Genera una serie temporal de 3 anios con tendencia creciente y estacionalidad
- Calcula medias moviles de 7, 30 y 90 dias
- Resamplea a frecuencia mensual y trimestral
- Calcula el crecimiento year-over-year
- Descompone la serie en tendencia, estacionalidad y residuos
- Identifica los meses de mayor y menor venta
💡 Concepto Clave
Revisemos los puntos más importantes de esta lección antes de continuar.
Resumen
- pd.date_range(): Generar rangos de fechas
- resample(): Cambiar frecuencia temporal (diario a mensual, etc.)
- rolling(): Medias moviles para suavizar datos
- pct_change(): Calcular cambios porcentuales
- seasonal_decompose(): Separar tendencia, estacionalidad y ruido
- Siempre visualiza tus series temporales antes de analizarlas
🧠 Pon a prueba tu conocimiento
¿Cuál es el aspecto más importante que aprendiste en esta lección?
- Comprendo el concepto principal y puedo explicarlo con mis palabras
- Entiendo cómo aplicarlo en mi situación específica
- Necesito repasar algunas partes antes de continuar
- Quiero ver más ejemplos prácticos del tema
✅ ¡Excelente! Continúa con la siguiente lección para profundizar más.