Pandas Análisis de series temporales
El análisis de series temporales es una parte importante del análisis de datos. Pandas proporciona funciones ricas para procesar y analizar datos de series temporales, incluyendo remuestreo, cálculo móvil, medias móviles, etc.
Operaciones básicas de series temporales
Crear series temporales
Ejemplo
import numpy as np
# Crear datos de series temporales
np.random.seed(42)
dates = pd.date_range("2024-01-01", periods=100, freq="D")
ts = pd.Series(
np.random.randn(100).cumsum() + 100,
index=dates
)
print("Datos de series temporales (primeros 10):")
print(ts.head(10))
print()
# Ver información
print(f"Tipo de índice: {type(ts.index)}")
print(f"Hora de inicio: {ts.index.min()}")
print(f"Hora de fin: {ts.index.max()}")
print(f"Duración: {ts.index.max() - ts.index.min()}")
Establecer la fecha como índice
Ejemplo
import numpy as np
# Crear un DataFrame y establecer el índice de fecha
df = pd.DataFrame({
"Fecha": pd.date_range("2024-01-01", periods=30, freq="D"),
"Ventas": np.random.randint(100, 500, 30),
"Visitantes": np.random.randint(50, 200, 30)
})
print("Antes de establecer:")
print(df.head())
print()
# Establecer la fecha como índice
df = df.set_index("Fecha")
print("Después de establecer:")
print(df.head())
print()
# Usar loc para consultar por fecha
print("Consultar de 2024-01-05 a 2024-01-10:")
print(df.loc["2024-01-05":"2024-01-10"])
Remuestreo
El remuestreo (Resampling) es el proceso de convertir datos de series temporales de una frecuencia a otra, lo que incluye el remuestreo ascendente (aumentar puntos de datos) y el remuestreo descendente (reducir puntos de datos).
Remuestreo descendente (Downsampling)
Ejemplo
import numpy as np
# Crear datos a nivel diario
np.random.seed(42)
dates = pd.date_range("2024-01-01", periods=90, freq="D")
ts = pd.Series(np.random.randint(100, 500, 90), index=dates)
print("Datos a nivel diario (primeros 10):")
print(ts.head(10))
print()
# Remuestrear por mes (suma)
monthly = ts.resample("M").sum()
print("Suma mensual:")
print(monthly)
print()
# Remuestrear por mes (promedio)
monthly_mean = ts.resample("M").mean()
print("Promedio mensual:")
print(monthly_mean)
Remuestreo ascendente (Upsampling)
Ejemplo
# Crear datos de baja frecuencia
dates = pd.date_range("2024-01-01", periods=3, freq="M")
ts = pd.Series([100, 200, 150], index=dates)
print("Datos a nivel mensual:")
print(ts)
print()
# Remuestrear a nivel diario (se necesita método de relleno)
ts_daily = ts.resample("D").ffill()
print("Remuestreo ascendente a nivel diario (primeros 10):")
print(ts_daily.head(10))
Métodos de remuestreo comunes
| Método | Descripción |
|---|---|
sum() |
Suma |
mean() |
Promedio |
max() / min() |
Máximo/Mínimo |
first() / last() |
Primer/último valor |
count() |
Número de valores no nulos |
ohlc() |
Apertura, máximo, mínimo, cierre (OHLC) |
Cálculo móvil (Rolling)
El cálculo móvil (Rolling) consiste en realizar cálculos con una ventana deslizante sobre los datos de la serie temporal. Se utiliza frecuentemente para calcular medias móviles, desviaciones estándar móviles, etc.
Media móvil
Ejemplo
import numpy as np
# Crear datos
np.random.seed(42)
dates = pd.date_range("2024-01-01", periods=30, freq="D")
ts = pd.Series(np.random.randint(100, 200, 30), index=dates)
# Calcular media móvil de 7 días
rolling_mean = ts.rolling(window=7).mean()
print("Media móvil de 7 días (primeros 10):")
print(rolling_mean.head(10))
print()
# Calcular desviación estándar móvil de 7 días
rolling_std = ts.rolling(window=7).std()
print("Desviación estándar móvil de 7 días:")
print(rolling_std.head(10))
Aplicación de funciones personalizadas con Rolling
Ejemplo
import numpy as np
ts = pd.Series(range(1, 11))
print("Datos originales:")
print(ts)
print()
# Suma móvil
print("Suma móvil de 3:")
print(ts.rolling(3).sum())
print()
# Máximo móvil
print("Máximo móvil de 3:")
print(ts.rolling(3).max())
print()
# Usar apply
print("Función personalizada de rolling 3 (rango):")
print(ts.rolling(3).apply(lambda x: x.max() - x.min()))
Visualización de datos de series temporales
Ejemplo
import numpy as np
# Crear datos de ejemplo
np.random.seed(42)
dates = pd.date_range("2024-01-01", periods=100, freq="D")
ts = pd.Series(
np.random.randn(100).cumsum() + 100,
index=dates
)
# Calcular media móvil
ma_7 = ts.rolling(7).mean()
ma_30 = ts.rolling(30).mean()
# Mostrar datos
print("Serie temporal + media móvil:")
print(f"Datos originales (primeros 5): {ts.head().tolist()}")
print(f"Media móvil de 7 días (primeros 10): {ma_7.dropna().head().tolist()}")
print(f"Media móvil de 30 días (últimos 5): {ma_30.dropna().tail().tolist()}")
Extracción de características de series temporales
Ejemplo
# Crear serie temporal
ts = pd.Series(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
index=pd.date_range("2024-01-01", periods=10, freq="D")
)
# Diferencia
diff = ts.diff()
print("Diferencia de primer orden:")
print(diff)
print()
# Cambio porcentual
pct = ts.pct_change()
print("Cambio porcentual:")
print(pct)
print()
# Desplazamiento
shifted = ts.shift(1)
print("Desplazamiento hacia atrás de 1:")
print(shifted)
Práctica: Análisis de datos de acciones
Ejemplo
import numpy as np
# Simular datos de acciones
np.random.seed(42)
n_days = 60
df = pd.DataFrame({
"Fecha": pd.date_range("2024-01-01", periods=n_days, freq="D"),
"Precio de apertura": 100 + np.random.randn(n_days).cumsum(),
"Precio de cierre": 100 + np.random.randn(n_days).cumsum(),
"Volumen de negociación": np.random.randint(1000000, 10000000, n_days)
})
df = df.set_index("Fecha")
# Calcular rendimiento diario
df["Rendimiento"] = df["Precio de cierre"].pct_change()
# Calcular la volatilidad (desviación estándar móvil de 7 días)
df["Volatilidad"] = df["Rendimiento"].rolling(7).std() * np.sqrt(252) # Anualizar
# Calcular líneas de media móvil
df["MA5"] = df["Precio de cierre"].rolling(5).mean()
df["MA20"] = df["Precio de cierre"].rolling(20).mean()
# Generar señales de trading (cruce dorado / cruce de muerte)
df["Señal"] = 0
df.loc[df["MA5"] > df["MA20"], "Señal"] = 1
df.loc[df["MA5"] < df["MA20"], "Señal"] = -1
print("Resultado del análisis de datos de acciones:")
print(df.tail(10))
Preguntas frecuentes
1. Fechas no continuas
Algunas series temporales no tienen datos todos los días (festivos, etc.), es necesario utilizarasfreqoreindexpara procesarlo.
2. Problema de zona horaria
Al procesar datos de múltiples zonas horarias, utilicetz_localizeytz_convertpara configurar y convertir la zona horaria.
3. Impacto de los valores faltantes
El cálculo móvil omite los valores faltantes por defecto, pero puede afectar la continuidad de los resultados.
Otras extensionesEl análisis de series temporales es una habilidad fundamental en campos como finanzas, meteorología e IoT. Pandas proporciona un conjunto completo de herramientas para procesar este tipo de datos.