En este proyecto veremos cómo implementar un flujo ETL (Extract-Transform-Load) en Python usando datos reales y abiertos disponibles en los servidores del transporte público de la ciudad de Londres (Transport for London).
Si estás suscrito a la Academia Online puedes acceder al enlace de descarga del código fuente (que se encuentra al final de este proyecto).
Contenido
Acceso a la API de Transport of London
El código fuente de este proyecto
¿Qué es un flujo ETL?
Es un proceso automatizado que siempre estará presente en proyectos de Ciencia de Datos y que busca tomar los datos disponibles en una o múltiples fuentes, procesarlos dependiendo de las necesidades del proyecto y luego llevarlos a un destino final (que también dependerá del uso que se quiera dar a esos datos):

Y este tipo de flujos aparecen en proyectos reales porque los datos rara vez vienen listos, y en general se encuentran almacenados en diferentes lugares, con diferentes formatos y además pueden contener errores o requerir algún tipo de limpieza o procesamiento previo antes de ser usados. Y precisamente el ETL automatiza todas estas fases, haciendo además que el proceso sea automático repetible y escalable.
Veamos qué hace cada una de las fases de un proceso ETL:
- Extracción (Extract, también conocida como ingesta): la entrada a este bloque son las fuentes de datos originales (archivos CSV, JSON, base de datos, etc.) y a la salida entrega los datos en bruto
- Transformación (Transform): toma los datos en bruto y entrega a la salida los datos pre-procesados (o transformados). Esta transformación de los datos dependerá de las características del proyecto. Por ejemplo, si se trata de datos tabulares, esta transformación podría consistir en la eliminación de datos faltantes o valores extremos, así como en la eliminación de variables irrelevantes o el escalamiento de algunas de esas variables.
- Carga (Load): esta fase toma los datos transformados y almacena los datos en el formato destino, donde el lugar y formato de destino dependerán de las siguientes fases proyecto. Por ejemplo, en este proyecto en particular simplemente haremos la carga a un archivo Parquet, pero en otros proyectos la carga llevaría los datos a un modelo para generar predicciones.
El problema de negocio
Asumiremos una situación hipotética: nos interesa conocer en tiempo real la disponibilidad de bicicletas en las diferentes estaciones en la ciudad de Londres.
Esto quiere decir que tendremos que recolectar datos asociados a dicha disponibilidad (fase de extracción), depurar estos datos para preservar la información relevante (fase de transformación) y luego llevar dichos datos a un archivo (fase de carga) que posteriormente pueda ser leído para generar la visualización.
Objetivo del proyecto
Teniendo en cuenta lo anterior, este será el objetivo de este proyecto:
Implementar un flujo ETL (extracción – transformación – carga) que permita tomar datos reales de disponibilidad de bicicletas en la ciudad de Londres y que almacene la información relevante en un archivo Parquet.
En este proyecto no incluiremos la fase de visualización (que hará parte de un próximo proyecto), pues el objetivo es enfocarnos en las fases ETL.
Acceso a la API de Transport of London
El insumo principal de este proyecto serán datos reales que podremos extraer de la API de la oficina Transport of London.
Esta API nos permite, bajo ciertas restricciones, acceder a datos en tiempo real sobre la disponibilidad de bicicletas en las diferentes estaciones que se encuentran en la ciudad de Londres.
Así que el primer paso en este proyecto es crear una cuenta de usuario y obtener las credenciales de acceso a la API. Para ello debemos seguir estos pasos:
- Vamos al sitio web de registro: Transport for London unified API
- Damos click en el enlace Register (registrarse)
- Diligenciamos el formulario introduciendo los datos convencionales (e-mail, contraseña, nombre y apellido) y damos click en el botón «Sign up»
- Después de unos minutos recibiremos un e-mail con un enlace para confirmar nuestra dirección de correo electrónico. Damos click en dicho enlace y esto nos llevará a la página de inicio de sesión («Sign in»)
- Estando en la página de inicio escribimos el e-mail y contraseña usados durante el registro
En este punto ya hemos configurado correctamente nuestro acceso a la plataforma. El siguiente paso es crear las «API keys» que son las claves de acceso que nos permitirán acceder a la descarga de datos usando la API a través de Python.
Para crear dichas «API keys» seguimos este procedimiento:
- Habiendo ingresado a la plataforma damos click en la opción Products, ubicada en el menú de navegación de la parte superior:

- Al hacer esto veremos un listado de los productos a los que tendremos acceso de forma gratuita. Seleccionamos la opción «500 requests per min» que nos permitirá acceder a la API a la cual podremos enviar máximo 500 solicitudes («requests») por minuto:

- En este punto aparecerá un cuadro de diálogo para crear una suscripción. Así que escribimos un nombre para esta suscripción (por ejemplo «api_bikepoint») y oprimimos «Subscribe»:

- En este punto llegaremos a la página de perfil de usuario y en la sección suscripciones veremos el listado de suscripciones que hemos creado:

Y acá lo que nos interesa es el campo indicado con la etiqueta «Primary key» que contendrá precisamente la API key que usaremos para descargar la información.
Por defecto, esta «Primary key» está oculta, así que damos click en el enlace que dice «Show» y luego copiamos dicha clave (conformada por caracteres y números). Esta clave será requerida para poder acceder a la API desde Python.
¡Y listo! Con esto ya podemos enfocarnos en la parte central de este proyecto: la implementación del flujo ETL. Comencemos viendo la fase de extracción.
Fase de extracción (E)
En esta fase vamos a acceder a la API directamente desde Python y haremos la descarga de los datos sobre la disponibilidad de bicicletas.
Estos datos están almacenados en formato JSON y los podremos manipular usando diccionarios de Python.
Así que en adelante toda la implementación la haremos en un notebook de Jupyter, aunque más adelante, en un próximo proyecto, veremos cómo organizar este código en archivos de Python (extensión .py) para incluir posteriormente la fase de visualización.
Comencemos importando las librerías requeridas para este proyecto. Usaremos «requests» (para poder acceder a la API) y Pandas (para la fase de transformación de los datos):
import requests
import pandas as pd
A continuación crearemos tres variables que contendrán el nombre del producto que creamos en la API («api_bikepoint»), la API key y el «endpoint» de la API (es decir la URL desde la cual descargaremos los datos):
APP_ID = "api_bikepoint"
PRIMARY_KEY = "ad31f38c164d4bb2a2fb0d2dxkn57d12d42"
ENDPOINT = "https://api.tfl.gov.uk/BikePoint/"
⚠️ Nota importante: en el código anterior escribimos el APP_ID y el PRIMARY_KEY directamente en nuestro notebook. Este enfoque se puede usar sólo si ejecutamos nuestro código localmente. Si el código es ejecutado en la nube NO SE RECOMIENDA hacerlo (pues podemos exponer públicamente el acceso a la API) y es mejor manejarlo como variables de entorno⚠️
A continuación definimos los parámetros que le presentaremos a la función «requests» al momento de conectarnos con la API. Estos parámetros son en esencia el APP_ID y el PRIMARY_KEY que acabamos de crear:
params = {
"app_id": APP_ID,
"app_key": PRIMARY_KEY
}
Y con esto ya podemos enviar la solicitud a la API. Veamos primero esta parte de la implementación:
Contenido exclusivo para suscriptores
Si eres suscriptor accede en este enlace ó suscríbete a la Academia Online y accede a todo el contenido (lecciones en video, código fuente, sets de datos y descargas) de todos los cursos, proyectos y tutoriales.
¡Y listo, con esto ya hemos extraído la información relevante. Como los datos que acabamos de extraer están almacenados en un diccionario, no resulta fácil interpretar la información. Así que simplemente crearemos un DataFrame de Pandas a partir de este diccionario:
df = pd.DataFrame(info_stations)
Lo cual nos permite obtener una tabla similar a esta:

Así que en este punto ya hemos completado la fase de transformación de este proyecto. Nos queda únicamente la fase de carga, que veremos a continuación.
Fase de carga (L)
Recordemos que cada fase del proceso ETL depende de las particularidades del proyecto.
En el caso de la carga, esta fase depende del uso final que queramos dar a los datos (visualización, alimentar un modelo, etc.).
En este proyecto, tal como lo definimos en el objetivo inicial, lo que buscamos es almacenar los datos que acabamos de extraer en un archivo Parquet, que en un próximo proyecto usaremos para construir un dashboard de visualización de los datos en tiempo real.
Un archivo Parquet es un formato de datos binario muy usado en proyectos de Ciencia de Datos. En esencia permite almacenar datos en formato tabular y es un poco más eficiente (en términos de espacio de almacenamiento y tiempo de lectura) que un archivo CSV.
Y para implementar esta fase necesitamos sólo una línea de código, que tomará el DataFrame que acabamos de crear («df») y hará uso del método «to_parquet» para crear el archivo:
df.to_parquet('estaciones.parquet')
Y listo, en este punto ya hemos completado la fase de carga de este proyecto.
El código fuente de este proyecto
Contenido exclusivo para suscriptores
Si eres suscriptor accede en este enlace ó suscríbete a la Academia Online y accede a todo el contenido (lecciones en video, código fuente, sets de datos y descargas) de todos los cursos, proyectos y tutoriales.
Conclusión
Los flujos ETL (Extract-Transform-Load o Extraer-Transformar-Cargar) son muy comunes en proyectos de Ciencia de Datos.
La idea básica es que debemos buscar y recolectar los datos generalmente en fuentes externas (fase de extracción), para luego pre-procesarlos (fase de transformación) y finalmente llevarlos a un destino final (fase de carga).
Y cada una de estas fases tendrá sus propias particularidades dependiendo de las características propias del proyecto que estemos desarrollando.
Así que en este proyecto hemos visto un ejemplo concreto de un flujo ETL para el caso particular en el cual nos interesa conocer en tiempo real la disponibilidad de bicicletas en las diferentes estaciones en la ciudad de Londres.
Para ello, en la fase de extracción hemos accedido a la API de Transport for London, que provee información en tiempo real sobre dicha disponibilidad. Luego, en la fase de transformación, hemos procesado los datos provenientes del servidor (en formato JSON) para extraer la información relevante de cada estación. Y finalmente, en la etapa de carga, hemos almacenado el DataFrame resultante en un archivo Parquet.
A pesar de la simplicidad de este flujo ETL, este proyecto nos ha permitido tener una primera aproximación a este tipo de flujos que son muy comunes en Ciencia de Datos. En el próximo proyecto usaremos estos resultados como punto de partida para incluir una fase de visualización en donde crearemos un dashboard (o tablero de control) que nos permitirá ver en tiempo real la disponibilidad de las diferentes estaciones.
Y recuerda que si eres suscriptor y tienes alguna duda sobre este proyecto me puedes contactar directamente a través del formulario que encontrarás en la Intranet.
Volver al índice de Proyectos
