Demo: Usando la clase PaginaWeb del paquete bccr

Demo: Usando la clase PaginaWeb del paquete bccr

Randall Romero Aguilar

Esta actualización: 21 de diciembre de 2019.


Este cuaderno de Jupyter ilustra el uso del paquete de Python bccr, con el cual se facilita la descarga de cuadros de datos del sitio de Internet del Banco Central de Costa Rica.

Primero cargamos algunos paquetes: bccr para consultar datos del servicio web, pandas para manipular los datos en Python, numpy para calcular un promedio (más adelante), matplotlib para hacer gráficos.

In [1]:
import bccr
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn')
%matplotlib inline

1. Iniciando una consulta

Se crea un objeto (acá llamado consulta) de la clase PaginaWeb, sin pasarle argumentos.

In [2]:
consulta = bccr.PaginaWeb()

A diferencia de la descarga de datos con el Servicio Web, para descargar cuadros del sitio de internet del BCCR no es necesario inscribirse en la página de servicio web en https://www.bccr.fi.cr/seccion-indicadores-economicos/servicio-web/. No obstante, dado que actualmente este paquete de Python sólo da soporte a un subconjunto de los cuadros publicados (452 soportados de los más de 550 publicados), se recomienda que para aquellos cuadros que no se pueden aún descargar se descarguen los indicadores con la clase bccr.ServicioWeb.

2. Buscando una serie

Para descargar los datos de un cuadro del sitio web, es necesario saber su número de cuadro (este número en general no coincide con los códigos de variables del servicio web). Si ya ha abierto el cuadro en un navegador de Internet, la forma más sencilla de averiguar su número es ver la dirección URL, tal como se ilustra en la siguiente figura:
formulario

En la parte resaltada con un círculo rojo podemos observar que para el cuadro de “Medio Circulante”, el número de cuadro es el 125.

Para facilitar encontrar las series sin necesidad de navegar por el sitio web, la clase bccr.PaginaWeb provee la función buscar. Acá, por ejemplo, buscamos la frase 'medio circulante':

In [3]:
consulta.buscar(frase='medio circulante')
Out[3]:
title subtitle freq
chart
125 Medio circulante (M1) medido a nivel del sistema bancario – Saldos a fin de mes en millones de colones – M
164 Medio circulante (M1) medido a nivel del sistema financiero -Saldos a fin de mes en millones de colones- M

El resultado nos indica que los cuadros 125 y 164 corresponden a series que incluyen la frase exacta “medio circulante” en su descripción (una se refiere al sistema bancario y la otra al financiero). Si no sabemos la frase exacta pero sí varias palabras que deben aparecer en la descripción (en cualquier orden), usamos buscar con la opción todos

In [4]:
consulta.buscar(todos='numerario poder público')
Out[4]:
title subtitle freq
chart
54 Numerario en poder del público Medido a nivel de sistema bancario — -Saldos a fin de mes en millones de colones- M
177 Numerario en poder del público Medido a nivel del sistema financiero — -Saldos a fin de mes en millones de colones- M

También tenemos la opción de buscar series donde solo algunos de los términos aparecen en la descrición. Podemos además filtrar los resultados por la frecuencia de los datos (A anual, 6M semestral, Q trimestral, M mensual, W semanal, y Ddiaria.

In [5]:
consulta.buscar(algunos='japón yen', frecuencia='D')
Out[5]:
title subtitle freq
chart
357 Yen Japonés Con respecto al Dólar Estadounidense D

Si quisiéramos ver este último cuadro en el sitio de Internet del BCCR, simplemente usamos la funcion.web:

In [6]:
consulta.web(357)

Al ejecutar esta línea, se abre una nueva pestaña en su navegador de Internet predefinido con el cuadro solicitado. Esto resulta útil para verificar que los datos que descargamos en realidad coinciden con lo que esperábamos.

3. Descargando datos

3.1 Descargando una serie

Supongamos que queremos descargar datos del medio circulante (sistema bancario nacional). Arriba encontramos que su código es el 125. Para ello usamos la función datos:

In [7]:
M1 = consulta.datos(125).rename(columns={'125':'M1'})
M1.plot();

En la celda anterior, la parte .rename(columns={'125':'M1'}) es opcional, la utilizamos acá para cambiar el nombre de la serie. Observe que si bien podemos buscar la serie por código con un entero 125 o un texto '125', el resultado siempre dará el nombre de la variable como texto; por ello para renombrarla con .rename() es necesario usar un texto.

3.2 Descargando dos series de la misma frecuencia

Es posible además pasarle varios códigos a datos de una vez, ya sea directamente, en una lista [54,125] o tupla (54, 125) o bien las llaves de un diccionario (como se ilustra en la siguiente celda). Acá descargamos, además del medio circulante, en numerario en poder del público. El resultado será una tabla pandas.DataFrame, donde cada columna corresponde a una variable.

In [8]:
series = {'54':'NPP', '125':'M1'}
dinero = consulta.datos(series.keys()).rename(columns=series)
dinero.plot();

3.3 Cambiando la frecuencia de los datos

La función buscar ofrece la opción de cambiar la frecuencia de los datos, pero se recomienda tener precaución al utilizarla. Para ilustrar el motivo, suponga que deseamos construir una serie mensual del tipo de cambio promedio de MONEX. Primero buscamos un número de cuadro

In [9]:
consulta.buscar(todos='tipo cambio monex', frecuencia='D')
Out[9]:
title subtitle freq
chart
748 Tipo de cambio promedio MONEX En colones costarricenses D

Encontramos el 748. Cuando lo descargamos, indicamos que queremos una serie mensual freq='M', promediando func='mean' los datos diarios. Para ver los últimos 9 datos usamos .tail(9)

In [10]:
consulta.datos(748, freq='M',func='mean').tail(9)
Out[10]:
748
2019-04 408.027857
2019-05 420.195484
2019-06 391.538667
2019-07 409.794194
2019-08 367.513548
2019-09 405.761000
2019-10 432.284194
2019-11 403.120000
2019-12 426.704000

Los datos se ver demasiado inferiores a su verdadero valor! Resulta que si descargamos los datos originales (es decir, sin transformarlos)

In [11]:
consulta.datos(748).tail(12)
Out[11]:
748
2019-12-09 571.03
2019-12-10 572.02
2019-12-11 572.53
2019-12-12 569.97
2019-12-13 567.83
2019-12-14 0.00
2019-12-15 0.00
2019-12-16 566.97
2019-12-17 567.01
2019-12-18 567.40
2019-12-19 567.29
2019-12-20 567.62

vemos que se están reportando los datos de fin de semana (cuando no opera MONEX) como cero, en lugar de como datos faltantes (Esto puede originarse en que en los datos originales en Excel se haya calculado un promedio de celdas vacías, ¡las cuales Excel simplemente interpreta como ceros!). Para solucionarlo

In [12]:
consulta.datos(748).replace(0.0, np.nan).tail(12)
Out[12]:
748
2019-12-09 571.03
2019-12-10 572.02
2019-12-11 572.53
2019-12-12 569.97
2019-12-13 567.83
2019-12-14 NaN
2019-12-15 NaN
2019-12-16 566.97
2019-12-17 567.01
2019-12-18 567.40
2019-12-19 567.29
2019-12-20 567.62

con lo que

In [13]:
consulta.datos(748).replace(0.0, np.nan).resample('M').mean().tail(12)
Out[13]:
748
2019-01 607.694545
2019-02 611.235000
2019-03 604.098571
2019-04 601.304211
2019-05 592.093636
2019-06 587.308000
2019-07 577.437273
2019-08 569.646000
2019-09 579.658571
2019-10 582.643913
2019-11 575.885714
2019-12 568.938667

3.4 Descargando varias series de distinta frecuencia

La función datos permite descargar variables de distinta frecuencia, convirtiéndolos a una frecuencia común. Por ejemplo, suponga que desea, además de los datos anteriores, la serie de la tasa básica pasiva:

In [14]:
consulta.buscar(frase='tasa básica ')
Out[14]:
title subtitle freq
chart
17 Tasa Básica Diaria Porcentajes D
592 Tasa Básica Mensual Porcentajes a fin de mes M
2110 Cálculo de la Tasa Básica Pasiva Informe semanal ?

Vemos que el cuadro 17 tiene datos diarios y el 592 mensuales. El signo ? en la columna freq del cuadro 2110 significa que bccr.PaginaWeb aún no puede descargar estos datos.

Vemos que el código 17 es de una serie diaria, mientras que los datos de M1y NPP eran mensuales. En la siguiente celda, le indicamos a datos que debe convertir los datos de mayor a menor frecuencia usando un promedio (func=np.mean). Es posible además restringir el rango de los datos con los parámetros FechaInicio= y FechaFinal=.

In [15]:
series = {'54':'NPP', '125':'M1', '17':'Tasa básica'}
datos = consulta(series.keys(), func=np.mean).rename(columns=series)
datos.plot(subplots=True, figsize=[12,6]);
In [16]:
datos.tail()
Out[16]:
NPP M1 Tasa básica
2019-08 772528.602067 3.112189e+06 5.804839
2019-09 775677.647724 3.234048e+06 5.720000
2019-10 772766.319826 3.119567e+06 5.630645
2019-11 823485.229218 3.444727e+06 5.591667
2019-12 NaN NaN 5.608000

Es posible además restringir el rango de los datos con los parámetros FechaInicio= y FechaFinal=, aunque en algunos casos esto puede generar un error (¡estoy aún depurando el código!). Por lo pronto, es muy fácil restringir los datos usando las facilidades propias de pandas. Por ejemplo, para filtar los datos anteriores al rango 2016-2018:

In [17]:
datos['2016':'2018'].plot(subplots=True, figsize=[12,6]);

La frecuencia de los datos puede controlarse con el parámetro freq=. Si no se indica, se obtienen los datos de menor frecuencia. Es posible además indicar distintos métodos de conversión para func=, pasando un diccionario de la forma {código1: función1, código2: función2, ,...}.

4. Exportando datos

Finalmente, podemos exportar los datos de pandas a otros formatos; aquí se muestran los comandos para obtener archivos CSV (to_csv), Excel (to_excel) y Latex (to_latex):

In [18]:
datos.to_csv  ('datos.csv')
datos.to_excel('datos.xlsx')
datos.to_latex('datos.tex')

También podemos exportarlos a Stata (to_stata), aunque primero es necesario hacer un par de ajustes (indexar los datos por fechas en vez de períodos y quitar espacios y usar solo caracteres ASCII en los nombres de las columnas)

In [19]:
datos.index = datos.index.to_timestamp()
datos.rename(columns={'Tasa básica':'Tasa_basica'}, inplace=True)
datos.to_stata('datos.dta')

Hay más opciones disponibles. Se sugiere revisar la documentación de pandas en https://pandas.pydata.org/pandas-docs/stable/reference/frame.html#conversion

Advertencia

Este paquete ha sido desarrollado por Randall Romero Aguilar, y se ha compartido para facilitar la obtención de datos del BCCR a quien así lo necesite.
NO es un paquete oficial del Banco Central de Costa Rica, ni cuenta con aprobación o patrocinio del BCCR.

El paquete se ofrece gratuitamente pero SIN NINGUNA GARANTIA acerca de su correcto funcionamiento.Aunque he puesto el mayor esfuerzo en que este paquete funcione correctamente, algunos errores pueden persistir. Si encuentra alguno, o bien si tiene sugerencias acerca de futuras mejoras, por favor envíeme un correo a randall.romero@outlook.com.

© Randall Romero Aguilar, 2015-2019