Python para Economía

Introducción a Python
Aplicado a Series Temporales en Economía


AUTORES

David Giuliodori & Alejandro Rodriguez

El Papel del Análisis de Datos en la Economía Moderna

La economía moderna se ha transformado en una disciplina cada vez más empírica, donde la validación de teorías y la comprensión de fenómenos complejos dependen intrínsecamente del análisis de datos. Esta evolución ha hecho que el desarrollo de sólidas habilidades en ciencia de datos sea fundamental para los economistas. En este contexto, Python ha emergido como una herramienta líder, apreciada por su versatilidad y su vasto ecosistema de bibliotecas especializadas.

Dominar esta herramienta permite a los estudiantes trascender los marcos teóricos y aplicarlos a situaciones económicas concretas, lo que enriquece su formación y les proporciona una comprensión más profunda y aplicable de la economía.

Fundamentos de Python

Tipos de Datos y Estructuras

Una comprensión fundamental de los tipos y estructuras de datos de Python es esencial. Los tipos de datos básicos (int, float, str, bool) son los ladrillos de la información, mientras que las estructuras de datos (listas, diccionarios) nos permiten organizarla.

# Tipos de Datos
tasa_inflacion = 8.5  # float
anio = 2023        # int
pais = "Argentina"   # str
en_recesion = True    # bool

# Estructuras de Datos
ipc_serie = [8.4, 7.7, 11.0, 8.8] # Lista: ideal para series de tiempo
dato_actual = {             # Diccionario: para observaciones con múltiples variables
    'pbi_var': -2.5,
    'desempleo': 6.9
}
print(f"La inflación del primer mes fue: {ipc_serie[0]}%")
print(f"La tasa de desempleo actual es: {dato_actual['desempleo']}%")

Control de Flujo y Funciones

Las estructuras de control (if/else, for) permiten que nuestros programas tomen decisiones y repitan tareas. Las funciones (def) nos permiten encapsular esta lógica para reutilizarla, haciendo nuestro código más limpio y modular.

# Función para clasificar el crecimiento económico
def clasificar_crecimiento(tasa_pbi):
    if tasa_pbi > 2.0:
        return "Fuerte Expansión"
    elif tasa_pbi > 0:
        return "Expansión Moderada"
    else:
        return "Recesión"

# Bucle para analizar varias tasas
tasas_anuales = [2.5, -1.0, 0.5]
for tasa in tasas_anuales:
    clasificacion = clasificar_crecimiento(tasa)
    print(f"Una tasa de {tasa}% se clasifica como: {clasificacion}")

Computación Numérica con NumPy

Arrays de NumPy: Operaciones Numéricas Eficientes

NumPy es la piedra angular de la computación numérica en Python. Su objeto ndarray permite operaciones matemáticas eficientes sobre grandes volúmenes de datos (vectorización), lo cual es órdenes de magnitud más rápido que usar bucles.

import numpy as np

# Ejemplo: Ajustar salarios por inflación
salarios = np.array([50000, 65000, 80000])
inflacion = 0.45 # 45%

# Operación vectorizada: rápida y concisa
salarios_ajustados = salarios * (1 + inflacion)
print(f"Salarios ajustados: {salarios_ajustados}")

Atributos, Indexación y Slicing de Arrays

Entender las propiedades de un array y cómo acceder a sus elementos es fundamental. Los atributos como .shape y .dtype nos dan información sobre la estructura del array. La indexación y el slicing nos permiten seleccionar subconjuntos de datos de manera eficiente.

import numpy as np

# Creamos un array de 2 dimensiones (matriz)
datos = np.array([[1, 2, 3], [4, 5, 6]])

# Atributos
print(f"Forma del array: {datos.shape}") # (2 filas, 3 columnas)
print(f"Tipo de datos: {datos.dtype}") # int64

# Indexación (acceder a un elemento: fila 0, columna 2)
elemento = datos[0, 2]
print(f"Elemento en [0, 2]: {elemento}") # 3

# Slicing (acceder a una columna entera: todas las filas, columna 1)
columna_1 = datos[:, 1]
print(f"Segunda columna: {columna_1}") # [2 5]

Manipulación de Datos con Pandas

Lectura de Datos desde Archivos

El punto de partida de casi todo análisis es cargar datos. Pandas ofrece funciones robustas para leer una gran variedad de formatos. Las más comunes son pd.read_csv() para archivos de texto delimitado (CSV) y pd.read_excel() para hojas de cálculo de Excel.

Es fundamental prestar atención a los parámetros de estas funciones para asegurar una carga correcta de los datos. Algunos de los más importantes para read_csv son:

  • sep: El delimitador de columnas (por defecto es ',', pero en Latinoamérica es común ';').
  • decimal: El separador de decimales (por defecto es '.', a veces es ',').
  • index_col: Especifica qué columna debe usarse como índice del DataFrame.
  • parse_dates: Una lista de columnas que Pandas intentará convertir automáticamente a formato de fecha, crucial para series de tiempo.
import pandas as pd
from io import StringIO

# En un caso real, usarías la ruta a tu archivo:
# df = pd.read_csv('datos/economia.csv', sep=';', decimal=',', index_col='Fecha', parse_dates=True)

# Para que este ejemplo sea reproducible, simulamos un archivo CSV:
data_csv = """Fecha;PBI;Inflacion
2023-01-01;102.5;7.7
2023-02-01;103.1;8.4
2023-03-01;102.9;11.0"""

# Usamos StringIO para que pandas lea el string como si fuera un archivo
df_simulado = pd.read_csv(
    StringIO(data_csv), 
    sep=';', 
    index_col='Fecha', 
    parse_dates=True
)

print(df_simulado)
print("\nTipo de dato del índice:", type(df_simulado.index))

Selección y Filtrado Interactivo

Una vez cargados los datos, la habilidad más fundamental es aprender a seleccionar y filtrar. Haz clic en los botones para ver el código de Pandas y cómo afecta a la tabla de datos de ejemplo.

Comandos de Pandas

Resultado del DataFrame

Limpieza y Tratamiento de Datos Faltantes

En el mundo real, los datos rara vez son perfectos. Una de las tareas más comunes es lidiar con los datos faltantes (NaN). Pandas ofrece métodos sencillos para detectarlos y tratarlos.

import pandas as pd
import numpy as np

data = {'Tasa_Desempleo': [3.5, 3.6, np.nan, 3.7],
        'Tasa_Interes': [5.25, 5.25, 5.50, np.nan]}
df = pd.DataFrame(data, index=['2023-Q1', '2023-Q2', '2023-Q3', '2023-Q4'])

print("Datos faltantes por columna:")
print(df.isnull().sum())

# Estrategia 1: Eliminar filas con cualquier dato faltante
print("\nDataFrame sin filas con NaN:")
print(df.dropna())

# Estrategia 2: Rellenar NaN con el valor anterior (forward-fill)
print("\nDataFrame con NaN rellenados:")
print(df.fillna(method='ffill'))

Rezagos, Diferencias y Ventanas Móviles

El análisis de series temporales se basa en transformaciones específicas de los datos. Pandas las hace triviales:

  • .shift(n): Crea un rezago (lag) de n períodos, fundamental para modelos autorregresivos.
  • .diff(n): Calcula la diferencia de orden n, usada para estabilizar la media de una serie y alcanzar la estacionariedad.
  • .rolling(window): Calcula una estadística (como .mean() o .std()) sobre una ventana móvil, útil para suavizar una serie y visualizar tendencias.
# 'unrate' es nuestro DataFrame de desempleo de FRED
import pandas as pd
data = {'PBI': [100, 102, 105, 103, 106]}
idx = pd.date_range('2023-01-01', periods=5, freq='Q')
df = pd.DataFrame(data, index=idx)

# Crear un rezago de 1 período del PBI
df['PBI_rezago_1'] = df['PBI'].shift(1)

# Crear la diferencia de 1er orden del PBI
df['PBI_diferencia_1'] = df['PBI'].diff(1)

# Calcular la media móvil de 12 meses para suavizar la serie
unrate['12M_MA'] = unrate['UNRATE'].rolling(window=12).mean()



# Graficar la serie original y su media móvil
unrate[['UNRATE', '12M_MA']].plot(figsize=(10,6), title='Tasa de Desempleo y Media Móvil de 12 Meses')

print(df)

Agrupación y Agregación de Datos

El método .groupby() es una de las herramientas más potentes de Pandas. Permite agrupar datos basándose en una o más columnas y luego aplicar una función de agregación (como .mean(), .sum(), .count()) a cada grupo.

import pandas as pd
data = {
    'Año': [2022, 2022, 2023, 2023],
    'Trimestre': ['T1', 'T2', 'T1', 'T2'],
    'Crecimiento_PBI': [1.2, 0.8, -0.5, 0.2]
}
df = pd.DataFrame(data)
# Calcular el crecimiento promedio por año
crecimiento_anual = df.groupby('Año')['Crecimiento_PBI'].mean()
print(crecimiento_anual)

Combinando DataFrames (Merge & Join)

En economía es muy común necesitar combinar datos de diferentes fuentes (ej: PBI, población, inflación). El método pd.merge() es la herramienta principal para realizar uniones entre DataFrames, similar al JOIN de SQL. La clave es el parámetro how, que define la lógica de la unión.

import pandas as pd

# DataFrame de datos del PBI (miles de millones USD)
data1 = {'Anio': [2021, 2022, 2023],
         'PBI': [605, 632, 622]}
df1 = pd.DataFrame(data1)

# DataFrame de datos de Población (millones)
data2 = {'Anio': [2022, 2023, 2024],
         'Poblacion': [46.2, 46.6, 47.0]}
df2 = pd.DataFrame(data2)

# Ejemplo de combinación usando un 'left' join
df_combinado = pd.merge(df1, df2, on='Anio', how='left')

print("--- df1 (PBI) ---")
print(df1)
print("\n--- df2 (Población) ---")
print(df2)
print("\n--- Resultado del Merge (left) ---")
print(df_combinado)

Prueba Interactiva de Joins

Haz clic en los botones para visualizar el resultado de cada tipo de join.

Tablas Originales

PBI (df1)
Población (df2)

Código y Resultado de la Unión

Obtención de Datos por API

Datos Económicos con `pandas-datareader`

Gran parte del análisis económico moderno se nutre de datos públicos. La librería `pandas-datareader` permite conectarse directamente a fuentes como la Reserva Federal de St. Louis (FRED), que aloja cientos de miles de series económicas (PBI, inflación, desempleo, etc.).

Cada serie en FRED tiene un código único (ej: `GDPC1` para el PBI de EE.UU.). Podemos descargar estos datos directamente a un DataFrame de Pandas, listos para analizar.

!pip install pandas_datareader
import pandas_datareader.data as web
import datetime

# Definir fechas de inicio y fin
start = datetime.datetime(2020, 1, 1)
end = datetime.datetime(2023, 12, 31)

# Descargar la Tasa de Desempleo de EEUU (UNRATE) desde FRED
unrate = web.DataReader('UNRATE', 'fred', start, end)

print("Últimos 5 datos de desempleo:")
print(unrate.tail())

Datos Financieros con `yfinance`

Para datos de mercados financieros (precios de acciones, índices, ETFs), la librería yfinance es una herramienta excepcional. Permite descargar datos históricos directamente desde Yahoo! Finance con apenas unas líneas de código.

!pip install yfinance
import yfinance as yf
import matplotlib.pyplot as plt

# Crear un objeto "Ticker" para el índice S&P 500
sp500 = yf.Ticker("^GSPC")

# Obtener el historial de precios para los últimos 5 años
hist_sp500 = sp500.history(period="5y")

# Graficar la serie de precios de cierre para replicar el gráfico
plt.figure(figsize=(10, 6))
hist_sp500['Close'].plot(title="Historial de Precios S&P 500 (Últimos 5 años)")
plt.ylabel("Precio de Cierre (USD)")
plt.xlabel("Fecha")
plt.grid(True)
plt.show()

Visualización de Datos Económicos

Visualización Exploratoria con Seaborn

La visualización es clave para descubrir patrones, tendencias y relaciones. Seaborn, construida sobre Matplotlib, permite crear gráficos estadísticos complejos con poco código, integrándose perfectamente con Pandas. A continuación, se visualiza una serie simulada del PIB.

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# Suponiendo que 'df_pib' tiene un DatetimeIndex y una columna 'Valor'
plt.figure(figsize=(10, 6))
sns.lineplot(data=df_pib, x=df_pib.index, y='Valor')
plt.title('Evolución del PIB Simulado')
plt.xlabel('Fecha')
plt.ylabel('Valor (en millones)')
plt.grid(True)
plt.show()

Pruebas de Hipótesis en Economía

Las pruebas de hipótesis nos permiten tomar decisiones basadas en datos para validar afirmaciones económicas. Una de las más comunes es la prueba t para muestras independientes, que se usa para comparar las medias de dos grupos. Por ejemplo: ¿un programa de capacitación laboral aumentó significativamente el ingreso promedio de los participantes en comparación con un grupo de control?

Usamos la biblioteca scipy.stats para realizar estas pruebas. La clave es interpretar el p-valor: si es bajo (típicamente < 0.05), rechazamos la hipótesis nula (de que no hay diferencia) y concluimos que la diferencia observada es estadísticamente significativa.

import numpy as np
from scipy import stats

# Ingresos de dos grupos (ej. con y sin programa de capacitación)
grupo_control = np.array([25000, 27000, 26500, 24000, 28000])
grupo_tratamiento = np.array([28000, 31000, 29500, 30000, 32000])

# Realizar la prueba t para muestras independientes
t_stat, p_valor = stats.ttest_ind(grupo_tratamiento, grupo_control)

print(f"Estadístico t: {t_stat:.2f}")
print(f"P-valor: {p_valor:.4f}")

if p_valor < 0.05:
    print("La diferencia es estadísticamente significativa.")
else:
    print("No hay evidencia de una diferencia significativa.")

Análisis de Regresión con Statsmodels

La regresión lineal es quizás la herramienta más fundamental en econometría. Nos permite modelar la relación entre una variable dependiente (Y) y una o más variables independientes (X). Por ejemplo, podemos estimar cómo la tasa de interés (X) afecta la inversión (Y).

La biblioteca statsmodels ofrece una sintaxis de fórmula muy intuitiva (similar a R) para definir y estimar estos modelos. El resultado principal es la tabla de resumen, que nos da los coeficientes estimados, su significancia estadística (P>|t|) y medidas de ajuste del modelo como el R-cuadrado.

import pandas as pd
import statsmodels.formula.api as smf

# Datos simulados de consumo e ingreso
data = {'ingreso': [10, 12, 15, 18, 22, 25],
        'consumo': [8, 9, 11, 15, 18, 20]}
df = pd.DataFrame(data)

# Definir y ajustar el modelo de regresión lineal
# La fórmula 'consumo ~ ingreso' significa "explicar consumo en función de ingreso"
modelo = smf.ols('consumo ~ ingreso', data=df).fit()

# Imprimir el resumen con los resultados
print(modelo.summary())

Visualizar la relación con un diagrama de dispersión y la línea de regresión ajustada es un paso crucial para interpretar los resultados.

Análisis de Series Temporales

Índices de Tiempo y Transformaciones

El pilar del análisis de series temporales en Pandas es el DatetimeIndex. Permite operaciones potentes como el remuestreo (.resample()) para cambiar la frecuencia y las ventanas móviles (.rolling()) para suavizar las series y revelar tendencias.

import pandas as pd
# df es un DataFrame con un DatetimeIndex
# Suavizar la serie con una media móvil de 7 días
df['valor_suavizado'] = df['valor'].rolling(window=7).mean()
# Cambiar la frecuencia de diaria a mensual
df_mensual = df['valor'].resample('M').mean()

Modelo ARIMA

Descomposición y Autocorrelación

Antes de modelar, descomponemos una serie en Tendencia, Estacionalidad y Residuo. Luego, usamos los gráficos de la Función de Autocorrelación (ACF) y Parcial (PACF) para entender la "memoria" de la serie, lo cual es fundamental para especificar modelos como ARIMA.

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt
# Suponiendo que 'serie_estacionaria' es una Serie de Pandas
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))
plot_acf(serie_estacionaria, ax=ax1, lags=20)
ax1.set_title('Función de Autocorrelación (ACF)')
plot_pacf(serie_estacionaria, ax=ax2, lags=20)
ax2.set_title('Función de Autocorrelación Parcial (PACF)')
plt.show()

Modelos de Suavizado: SMA y SES

Los modelos de suavizado son técnicas intuitivas para pronosticar. La Media Móvil Simple (SMA) promedia observaciones pasadas, mientras que el Suavizado Exponencial Simple (SES) asigna pesos que decrecen exponencialmente.

from statsmodels.tsa.api import SimpleExpSmoothing
# df_ventas es una Serie de Pandas
modelo_ses = SimpleExpSmoothing(df_ventas, initialization_method="estimated").fit()
pronostico = modelo_ses.forecast(3) # Pronosticar 3 períodos
print("Pronóstico SES:", pronostico)

Modelos ARIMA para Pronósticos

Los modelos ARIMA (Autoregressive Integrated Moving Average) son una de las herramientas más poderosas para el pronóstico de series de tiempo. Modelan la próxima observación como una función lineal de las observaciones pasadas (AR), errores pasados (MA) y diferenciaciones para hacer la serie estacionaria (I).

La elección de los órdenes (p, d, q) del modelo se guía por el análisis de los gráficos ACF y PACF. Una vez ajustado el modelo, podemos usarlo para generar pronósticos fuera de la muestra con intervalos de confianza.

from statsmodels.tsa.arima.model import ARIMA
import pandas as pd

# Suponiendo que 'serie_pbi' es una serie de tiempo de Pandas
# Ajustamos un modelo ARIMA(p=1, d=1, q=1)
modelo = ARIMA(serie_pbi, order=(1, 1, 1))
resultado = modelo.fit()

# Generar un pronóstico para los próximos 4 trimestres
pronostico = resultado.forecast(steps=4)
print("Pronóstico PBI (próximos 4 trimestres):")
print(pronostico)

Modelado Econométrico Avanzado

Una vez dominadas las bases, podemos explorar técnicas econométricas más sofisticadas que nos permiten capturar dinámicas complejas en los datos, como la volatilidad variable en el tiempo y las interdependencias entre múltiples variables.

Estadística Profunda: Pruebas de Estacionariedad

La mayoría de los modelos de series de tiempo requieren que los datos sean estacionarios (que su media, varianza y autocorrelación no cambien con el tiempo). Una serie no estacionaria puede llevar a regresiones espurias y conclusiones erróneas. La prueba más común para verificar la estacionariedad es la Prueba de Dickey-Fuller Aumentada (ADF).

La hipótesis nula de la prueba ADF es que la serie tiene una raíz unitaria (es decir, no es estacionaria). Si el p-valor es menor a 0.05, rechazamos la hipótesis nula y concluimos que la serie es estacionaria.

from statsmodels.tsa.stattools import adfuller
# Suponiendo que 'serie_pbi' es una serie de Pandas
resultado_adf = adfuller(serie_pbi.dropna())
print(f'Estadístico ADF: {resultado_adf[0]:.2f}')
print(f'p-valor: {resultado_adf[1]:.4f}')

if resultado_adf[1] < 0.05:
    print('Resultado: La serie es estacionaria.')
else:
    print('Resultado: La serie no es estacionaria.')

Modelos GARCH para Volatilidad

En finanzas, es común observar "clusters de volatilidad": períodos de alta volatilidad seguidos por más alta volatilidad, y viceversa. Los modelos GARCH (Generalized Autoregressive Conditional Heteroskedasticity) están diseñados para capturar esta dinámica, modelando la varianza condicional de la serie.

Son fundamentales para la gestión de riesgos, la valoración de opciones y el análisis de mercados financieros. La biblioteca arch es el estándar en Python para estos modelos.

from arch import arch_model
# 'retornos' es una serie de Pandas de retornos de un activo
# Ajustamos un modelo GARCH(1,1) estándar
modelo_garch = arch_model(retornos, vol='Garch', p=1, q=1)
resultado_garch = modelo_garch.fit(disp='off') # disp='off' para no imprimir el output de convergencia
print(resultado_garch.summary())

Modelos VAR para Múltiples Series

Cuando queremos analizar las interdependencias dinámicas entre varias series de tiempo (ej. cómo se afectan mutuamente la inflación, el PBI y la tasa de interés), usamos Vectores Autorregresivos (VAR). Un modelo VAR trata a cada variable como una función lineal de sus propios valores pasados y de los valores pasados de todas las demás variables en el sistema.

Son muy utilizados en macroeconomía para análisis de impulso-respuesta y pronósticos conjuntos.

from statsmodels.tsa.api import VAR
# 'df_macro' es un DataFrame con columnas 'inflacion', 'pbi', 'interes'
# Es crucial que las series sean estacionarias antes de usar VAR
modelo_var = VAR(df_macro_estacionario)
resultado_var = modelo_var.fit(maxlags=4, ic='aic') # Selecciona el lag óptimo
# Pronosticar 5 períodos hacia adelante
pronostico_var = resultado_var.forecast(df_macro_estacionario.values[-resultado_var.k_ar:], steps=5)
print(pronostico_var)

Estadística Profunda: Causalidad de Granger

La prueba de Causalidad de Granger es una prueba de hipótesis estadística para determinar si una serie de tiempo es útil para pronosticar otra. Si el conocimiento pasado de la serie X reduce el error de pronóstico de la serie Y, entonces decimos que "X Granger-causa a Y".

Es importante no interpretar esto como causalidad en el sentido filosófico, sino como una medida de predictibilidad. Un p-valor bajo (< 0.05) sugiere la presencia de Causalidad de Granger.

from statsmodels.tsa.stattools import grangercausalitytests
# 'df_causal' es un DataFrame con dos columnas, ej. 'gasto_publico' e 'pbi'
max_lags = 4
resultado_granger = grangercausalitytests(df_causal[['pbi', 'gasto_publico']], maxlag=max_lags, verbose=False)
# Analizar el p-valor para cada lag
for lag in range(1, max_lags + 1):
    p_valor = resultado_granger[lag][0]['ssr_ftest'][1]
    print(f'Lag {lag}: P-valor = {p_valor:.4f}')

Introducción al Machine Learning para Pronósticos

Preparando Datos para Modelos de ML

A diferencia de los modelos ARIMA que entienden la estructura temporal de forma inherente, los modelos de Machine Learning (ML) como los bosques aleatorios (`Random Forest`) requieren que transformemos la serie de tiempo en un problema de aprendizaje supervisado. Esto se logra creando un "feature matrix" donde las columnas son los rezagos de la variable, que actuarán como predictores, y la variable objetivo es el valor actual.

# Función para crear características (rezagos) y el objetivo
def crear_features_series_tiempo(serie, n_lags=5):
    df = pd.DataFrame()
    for i in range(n_lags, 0, -1):
        df[f'lag_{i}'] = serie.shift(i)
    df['target'] = serie
    return df.dropna()

datos_ml = crear_features_series_tiempo(unrate['UNRATE'], n_lags=5)
X = datos_ml.drop('target', axis=1) # Predictores (rezagos)
y = datos_ml['target']             # Objetivo (valor actual)

print(X.head())

Entrenando un `RandomForestRegressor` con Scikit-Learn

Scikit-Learn es la librería por excelencia para el Machine Learning en Python. Su API es uniforme y fácil de usar: instanciamos un modelo, lo entrenamos con .fit(X, y) y hacemos predicciones con .predict(X_nuevos).

Los modelos como `RandomForestRegressor` son muy potentes porque pueden capturar relaciones no lineales complejas entre los predictores y la variable objetivo, a menudo superando a los modelos lineales clásicos en tareas de pronóstico puro.

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split

# Dividir los datos en entrenamiento y prueba (respetando el orden temporal)
train_size = int(len(X) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]

# Instanciar y entrenar el modelo
modelo_rf = RandomForestRegressor(n_estimators=100, random_state=42)
modelo_rf.fit(X_train, y_train)

# Hacer predicciones en el conjunto de prueba
predicciones_rf = modelo_rf.predict(X_test)

# Comparar predicciones con valores reales
df_comparacion = pd.DataFrame({'real': y_test, 'prediccion_rf': predicciones_rf})
print(df_comparacion.head())

Caso Aplicado: Análisis de la Coyuntura Económica Argentina

Fase 1: Obtención y Preparación de Datos

El primer paso es recolectar y preparar los datos. En un proyecto real, usaríamos pd.read_csv() o APIs. Para este ejemplo, crearemos un DataFrame con datos mensuales simulados de indicadores clave: Estimador Mensual de Actividad Económica (EMAE), Inflación (IPC) y el tipo de cambio Dólar CCL.

import pandas as pd
import numpy as np

# 1. Creación de datos simulados realistas
fechas = pd.date_range('2022-01-01', '2024-12-01', freq='MS')
n = len(fechas)
emae = 145 + np.cumsum(np.random.randn(n) * 0.5) # Base 145, con tendencia
ipc = 6 + np.sin(np.arange(n) * 0.5) * 2 + np.random.rand(n) * 2 # Base 6% con estacionalidad
ccl = 200 * np.exp(np.cumsum(np.random.randn(n) * 0.05)) # Crecimiento exponencial

df = pd.DataFrame({'EMAE': emae, 'IPC': ipc, 'CCL': ccl}, index=fechas)

# 2. Calcular variaciones mensuales para análisis
df['EMAE_var'] = df['EMAE'].pct_change() * 100
df['CCL_var'] = df['CCL'].pct_change() * 100

print("Últimos 5 meses de datos preparados:")
print(df.tail())

Fase 2: Análisis Exploratorio y Visualización

Visualizamos las series para entender su comportamiento inicial. Graficamos los niveles originales y también una matriz de correlación de sus variaciones para detectar posibles relaciones.

import seaborn as sns
import matplotlib.pyplot as plt

# Graficar la evolución de las variaciones
df[['EMAE_var', 'IPC', 'CCL_var']].plot(
    figsize=(12, 7), 
    title='Evolución de Indicadores Mensuales Clave',
    subplots=True, # Cada variable en su propio subgráfico
    layout=(3, 1),
    grid=True,
    legend=True
)
plt.tight_layout() # Ajusta el espaciado
plt.show()

# Matriz de Correlación
plt.figure(figsize=(8, 6))
sns.heatmap(df[['EMAE_var', 'IPC', 'CCL_var']].corr(), annot=True, cmap='viridis', fmt='.2f')
plt.title('Matriz de Correlación de Variaciones Mensuales')
plt.show()

Fase 3: Modelado y Pronóstico

Ahora, aplicamos un modelo ARIMA para pronosticar la inflación (IPC). El proceso incluye: 1) Verificar estacionariedad con la prueba ADF, 2) Analizar ACF/PACF para elegir órdenes (p,d,q), 3) Ajustar el modelo ARIMA y 4) Generar un pronóstico.

from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# 1. Verificar estacionariedad de la inflación (IPC)
ipc_series = df['IPC'].dropna()
adf_test = adfuller(ipc_series)
print(f'ADF p-valor para IPC: {adf_test[1]:.4f}') # Si > 0.05, no es estacionaria

# Suponiendo que no es estacionaria, la diferenciamos
ipc_diff = ipc_series.diff().dropna()

# 2. Analizar ACF y PACF para elegir p y q (d=1 por la diferenciación)
# plot_acf(ipc_diff), plot_pacf(ipc_diff) ... (código visual omitido)
# Basado en el análisis (hipotético), elegimos un ARIMA(1,1,1)

# 3. Ajustar el modelo ARIMA
modelo_ipc = ARIMA(ipc_series, order=(1, 1, 1)).fit()
print(modelo_ipc.summary())

# 4. Generar y graficar el pronóstico
pronostico = modelo_ipc.get_forecast(steps=6)
pronostico_df = pronostico.conf_int(alpha=0.05)
pronostico_df['mean'] = pronostico.predicted_mean

plt.figure(figsize=(10, 6))
plt.plot(ipc_series, label='Observado')
plt.plot(pronostico_df['mean'], label='Pronóstico', color='red')
plt.fill_between(pronostico_df.index, pronostico_df['lower IPC'], pronostico_df['upper IPC'], color='red', alpha=0.1)
plt.title('Pronóstico de Inflación (IPC) con ARIMA')
plt.legend()
plt.show()

Herramientas y Próximos Pasos

Google Colab: Mejores Prácticas

Google Colab es un entorno ideal para comenzar. Permite escribir y ejecutar código Python en la nube sin configuración. Es compatible con ipywidgets, una biblioteca para construir interfaces interactivas.

Mueve el control deslizante para ver un ejemplo de interactividad, cambiando la amplitud de la onda senoidal en tiempo real.

from ipywidgets import interact
import numpy as np
import matplotlib.pyplot as plt

def plot_sine(amplitud=1.0):
    x = np.linspace(0, 10, 100)
    y = amplitud * np.sin(x)
    plt.figure(figsize=(8, 4))
    plt.plot(x, y)
    plt.ylim(-5.5, 5.5)
    plt.title(f'Onda Senoidal con Amplitud {amplitud:.1f}')
    plt.show()

# Esto crearía el widget interactivo en Jupyter/Colab
interact(plot_sine, amplitud=(0.1, 5.0, 0.1));

Gestión de Paquetes con `pip` en Notebooks

Para poder usar librerías como Pandas, Statsmodels o Seaborn, primero deben estar instaladas en tu entorno de Python. La herramienta estándar para esto es `pip`, el gestor de paquetes de Python.

En entornos de notebook como Jupyter o Google Colab, puedes ejecutar comandos de la terminal directamente en una celda de código si los precedes con un signo de exclamación (!). Esta es la forma más sencilla de gestionar paquetes sin salir de tu análisis.

Los comandos más importantes son:

  • Instalar un paquete: !pip install nombre_del_paquete
  • Instalar una versión específica: !pip install nombre_del_paquete==1.2.3 (¡clave para la reproducibilidad!)
  • Actualizar un paquete: !pip install --upgrade nombre_del_paquete
  • Listar paquetes instalados: !pip list (muy útil para depurar y ver qué versiones tienes)
# Instalar la librería para modelos GARCH
!pip install arch

# Instalar una versión específica de statsmodels para asegurar la compatibilidad
!pip install statsmodels==0.14.0

# Actualizar pandas a su última versión
!pip install --upgrade pandas

# Mostrar los paquetes instalados en el entorno
!pip list

Vías para un Aprendizaje Adicional

Este curso es solo el comienzo. El campo del análisis econométrico es vasto y apasionante. Te animamos a explorar temas más avanzados para continuar tu desarrollo:

  • Modelos Avanzados de ST: Profundiza en modelos SARIMA (para estacionalidad compleja), VAR/VECM (para relaciones de cointegración), y modelos de Espacio de Estados (como Unobserved Components).
  • Adquisición Automatizada de Datos: Aprende a usar APIs de fuentes como el Banco Mundial, FMI, FRED, o librerías como yfinance para obtener datos financieros en tiempo real. El web scraping es otra habilidad valiosa.
  • Estadística Profunda: Además de las pruebas vistas, investiga sobre pruebas de normalidad de residuos, heterocedasticidad (como Breusch-Pagan), y de cointegración (como la prueba de Johansen).
  • Machine Learning para Pronósticos: Explora cómo algoritmos como Random Forest, Gradient Boosting (XGBoost, LightGBM) y redes neuronales (LSTM, GRU) pueden aplicarse a problemas de pronóstico económico, a menudo superando a los modelos clásicos.