Tu primer encuentro con el tiempo como dato
Imagina que intentas predecir las ventas de tu tienda online usando solo el precio medio del mes. Funcionaría bastante mal, ¿verdad? El problema no es que el precio no importe: es que estás ignorando el factor más obvio del universo: el orden en el tiempo.
Las series temporales son simplemente observaciones recogidas en intervalos consecutivos. Ventas diarias, temperaturas horarias, precios de cierre de una acción, latidos por minuto… Todo eso tiene en común que cada punto depende, en mayor o menor medida, de lo que pasó antes. Y ese detalle cambia por completo cómo debes analizarlos.
En este capítulo vas a aprender a pensar en el tiempo como una dimensión más de tus datos, no como una etiqueta decorativa.
¿Qué convierte unos datos en una serie temporal?
Un dataset normal registra filas independientes: clientes, productos, encuestas. Puedes barajarlas y el análisis sigue siendo válido. En una serie temporal, el orden importa. Barajar los datos destruye la información más valiosa: la dependencia entre el presente y el pasado.
Formalmente, una serie temporal es una secuencia:
$$Y_t = {y_1, y_2, y_3, …, y_t}$$
Donde cada $y_t$ es una observación en el instante $t$. La magia está en que $y_t$ no es un valor aislado: está relacionado con $y_{t-1}$, $y_{t-2}$ y, a veces, con el mismo mes del año pasado.
| Tipo de dato | Ejemplo | ¿Importa el orden? |
|---|---|---|
| Corte transversal | Encuesta de satisfacción | No |
| Serie temporal | Ventas diarias | Sí, totalmente |
| Panel de datos | Ventas diarias por tienda | Sí, y también hay grupos |
Nota clave: muchos algoritmos de machine learning asumen que las filas son independientes. Si les pasas una serie temporal sin más, estarás violando ese supuesto y los resultados serán engañosos.
Las cuatro caras de una serie temporal
Casi cualquier serie temporal se puede descomponer en cuatro componentes:
- Tendencia: movimiento a largo plazo. ¿Sube? ¿Baja? ¿Se mantiene plana?
- Estacionalidad: patrones que se repiten a intervalos fijos. Días de la semana, meses, estaciones.
- Ciclo: oscilaciones de más largo plazo, no necesariamente regulares. Los ciclos económicos son el ejemplo clásico.
- Ruido: la parte aleatoria que no explicas con lo anterior.
La forma más común de modelarlo es de manera aditiva:
$$Y_t = T_t + S_t + C_t + \varepsilon_t$$
No siempre necesitas los cuatro. A veces la serie solo tiene tendencia y ruido. Otras veces, la estacionalidad lo domina todo. El primer paso siempre es el mismo: dibujarla. Nunca empieces modelando sin mirar la gráfica.
Tu primera serie temporal con pandas
Vamos a crear una serie sintética que simule ventas mensuales durante cinco años. Tendrá tendencia creciente, un patrón estacional anual y algo de ruido. Así podremos ver cada componente por separado.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Fijamos semilla para que puedas reproducir los resultados
np.random.seed(42)
# 60 meses, desde enero de 2020
fechas = pd.date_range(start="2020-01-01", periods=60, freq="ME")
t = np.arange(60)
# Componentes
tendencia = 50 + 0.8 * t
estacionalidad = 10 * np.sin(2 * np.pi * t / 12)
ruido = np.random.normal(0, 4, 60)
# Serie completa
ventas = tendencia + estacionalidad + ruido
serie = pd.Series(ventas, index=fechas)
# Visualización
plt.figure(figsize=(10, 5))
plt.plot(serie, color="#1a1a1a", linewidth=2)
plt.title("Ventas mensuales simuladas")
plt.xlabel("Fecha")
plt.ylabel("Ventas")
plt.grid(True, alpha=0.3)
plt.show()
Fíjate en dos cosas del código. Primero, usamos pd.date_range con freq="ME" para tener un índice temporal de fin de mes. Segundo, convertimos el array de NumPy en una pd.Series con ese índice. Eso es lo que convierte unos números sueltos en una serie temporal manipulable.

La imagen muestra exactamente lo que acabamos de generar: arriba la serie completa y debajo cada componente aislado. Verlos separados es útil porque te obliga a pensar en qué parte quieres modelar.
El índice temporal es tu mejor aliado
Una vez que tienes un DatetimeIndex, pandas te da superpoderes. Puedes seleccionar rangos, cambiar frecuencias y calcular estadísticas móviles sin escribir bucles.
# Seleccionar un año concreto
serie_2022 = serie["2022"]
# Media móvil de 12 meses para suavizar la estacionalidad
media_movil = serie.rolling(window=12).mean()
# Re-muestrear a trimestres
serie_trimestral = serie.resample("QE").mean()
# Desplazar un periodo hacia delante (lag)
serie_lag1 = serie.shift(1)
La media móvil es especialmente útil. Si graficas la serie junto con su media de 12 meses, verás cómo la línea suavizada revela la tendencia subyacente que la estacionalidad estaba ocultando.
# Comparar serie original con media móvil de 12 meses
plt.figure(figsize=(10, 5))
plt.plot(serie, label="Ventas mensuales", color="#1a1a1a", linewidth=1.5)
plt.plot(serie.rolling(window=12).mean(), label="Media móvil 12 meses", color="#ffcc00", linewidth=2.5)
plt.title("Serie original vs tendencia suavizada")
plt.xlabel("Fecha")
plt.ylabel("Ventas")
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
La línea amarilla sigue la tendencia a largo plazo sin distraerse con los picos y valles estacionales. Es una forma rápida de ver hacia dónde se dirige la serie.
¿Depende hoy de ayer? El lag plot
Una forma visual de detectar dependencia temporal es el lag plot: graficas cada valor contra su valor anterior.
from pandas.plotting import lag_plot
plt.figure(figsize=(5, 5))
lag_plot(serie, lag=1, c="#1a1a1a", alpha=0.6)
plt.title("Lag plot: y(t) vs y(t-1)")
plt.grid(True, alpha=0.3)
plt.show()
Si los puntos forman una nube sin forma, no hay autocorrelación. Si se alinean en diagonal, el valor actual depende fuertemente del anterior. En nuestra serie sintética verás una diagonal clara: las ventas de un mes están ligadas a las del mes previo.
También puedes calcular la correlación numérica:
correlacion_lag1 = serie.corr(serie.shift(1))
print(f"Correlación con lag 1: {correlacion_lag1:.3f}")
Un valor alto confirma lo que intuías con el lag plot: el pasado importa.
Descomposición automática con statsmodels
Hasta ahora descompusimos la serie a mano. statsmodels puede hacerlo automáticamente con un modelo aditivo o multiplicativo.
from statsmodels.tsa.seasonal import seasonal_decompose
# Descomposición aditiva con período anual (12 meses)
resultado = seasonal_decompose(serie, model="additive", period=12)
fig = resultado.plot()
fig.set_size_inches(10, 8)
plt.suptitle("Descomposición aditiva de la serie", y=1.02)
plt.show()
Este gráfico separa observado, tendencia, estacional y residual en cuatro paneles. Es útil porque te da una versión “oficial” de la descomposición y te permite compararla con tu intuición visual.
Aditivo vs multiplicativo: usa aditivo cuando la estacionalidad tiene amplitud constante. Si los picos estacionales crecen o decrecen con la tendencia, prueba el modelo multiplicativo cambiando
model="multiplicative".
¿Por qué no usar una regresión lineal simple?
Es la pregunta que mucha gente se hace al empezar. Si quiero predecir ventas, ¿no puedo usar y = mx + b con el tiempo como x?
Puedes, pero solo si la serie es pura tendencia. En cuanto aparece estacionalidad, autocorrelación o ruido estructurado, una recta se queda corta. Peor aún: si usas los datos tal cual, los errores del modelo no serán independientes. Eso invalida los intervalos de confianza y hace que las predicciones sean poco fiables.
El análisis de series temporales no es un algoritmo más: es un cambio de mentalidad. Dejas de preguntarte “¿qué características explican y?” y empiezas a preguntarte “¿cómo depende y de sus propios valores pasados?”.
Resumen y próximo paso
En este capítulo has aprendido que una serie temporal es una secuencia ordenada donde el pasado influye en el presente. También has visto cómo descomponerla en tendencia, estacionalidad, ciclo y ruido, y cómo manipularla con pandas usando su índice temporal.
Antes de meter modelos complejos, necesitas dominar una idea central: la estacionariedad. Una serie estacionaria es mucho más fácil de modelar porque sus propiedades estadísticas no cambian con el tiempo. En el próximo capítulo veremos cómo detectarla, cómo transformar una serie no estacionaria en estacionaria y cómo ajustar tu primer modelo ARIMA.