Este proyecto de python corresponde a la carrera de Data Engineering ofrecido por IBM¶

EL script se encarga de recolectar informacion sobre la capitalizacion de mercado de los bancos mas grandes del mundo: En billones de USD , EUR , Libras Esterlinas y en Rupias Indias. El mismo crea un script bastante robusto para analisis posterior de los datos obtenidos. El script realiza lo siguiente:

  1. Recoleccion de datos(haciendo uso de webscrapping)
  2. Transformacion(toma los datos extraidos por la fase anterior de extraccion y les suma datos contenidos dentro de un archivo csv)
  3. Carga los datos transformados a un archivo csv de destino(para el posterior analisis de los datos)
  4. Carga a una base de datos con columnas previamente definidas
  5. Consulta a la base de datos 3 consultas sobre los datos , incluido un promedo sobre los billones de Libras de los mayores bancos del mundo
  6. Por ultimo crea un archivo de log el cual se encarga de tomar todos los pasos que esta haciendo el script para tener un registro de los mismos

Importacion de las Librerias Necesarias¶

In [2]:
!pip3 install pandas bs4 requests numpy
!wget https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMSkillsNetwork-PY0221EN-Coursera/labs/v2/exchange_rate.csv
Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (1.5.3)
Requirement already satisfied: bs4 in /usr/local/lib/python3.10/dist-packages (0.0.2)
Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (2.31.0)
Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (1.25.2)
Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-packages (from pandas) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas) (2023.4)
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.10/dist-packages (from bs4) (4.12.3)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests) (3.6)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests) (2.0.7)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests) (2024.2.2)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.1->pandas) (1.16.0)
Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.10/dist-packages (from beautifulsoup4->bs4) (2.5)
--2024-03-22 21:42:24--  https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMSkillsNetwork-PY0221EN-Coursera/labs/v2/exchange_rate.csv
Resolving cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud (cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud)... 169.45.118.108
Connecting to cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud (cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud)|169.45.118.108|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 45 [text/csv]
Saving to: ‘exchange_rate.csv.1’

exchange_rate.csv.1 100%[===================>]      45  --.-KB/s    in 0s      

2024-03-22 21:42:24 (26.2 MB/s) - ‘exchange_rate.csv.1’ saved [45/45]

In [3]:
from bs4 import BeautifulSoup
import requests as r
import pandas as pd
import numpy as np
import sqlite3 as db3
from datetime import datetime

Variables con los Datos Necesarios para la Extraccion¶

In [4]:
url = "https://web.archive.org/web/20230908091635/https://en.wikipedia.org/wiki/List_of_largest_banks"
atributos_tablas_extraccion = ["Nombre", "MC_USD_Billions"]
atributos_tablas_final = ["Nombre", "MC_USD_Billion", "MC_GBP_Billion", "MC_EUR_Billion", "MC_INR_Billion"]
nombre_db = 'Banks.db'
nombre_tabla = 'Largest_banks'
ruta_csv = './Largest_banks_data.csv'
log="code_log.txt"
csv_adicional="./exchange_rate.csv"

Creando la variable de Conexion con la Base de Datos¶

In [13]:
conexion = db3.connect("Banks.db")

Definiendo la Funcion Log¶

Se va a encargar de registrar todos los pasos que realiza el script dentro de un archivo de texto

In [6]:
def log_progress(mensaje):
    ''' Esta función registra el mensaje mencionado en una etapa determinada de la ejecución del código,
     en un archivo de registro'''
    ''' Aca se definen las entidades requeridas y se llama a las correspondientes.
    funciones en el orden correcto para completar el proyecto. .'''
    timestamp_format = '%Y-%h-%d-%H:%M:%S' # Año-Mes-Dia-Hora-Minutos-Segundos
    now = datetime.now() # fecha-hora actual
    timestamp = now.strftime(timestamp_format)
    with open("./etl_project_log.txt","a") as f:
        f.write(timestamp + ' : ' + mensaje + '\n')

Definiendo la Funcion de Extraccion¶

La misma va a recopilar los datos de la url solicitada, extrayendo los datos de una tabla en especifico

In [7]:
def extraer(url, atributos_tablas_extraccion):
    ''' Esta función extrae el requerido
    información del sitio web y la guarda en un marco de datos.
    La función devuelve el marco de datos para su posterior procesamiento.'''
    pagina= r.get(url).text # Extraer la pagina web como texto
    datos = BeautifulSoup(pagina, "html.parser") #Pasar archivo HTML a objeto
    df= pd.DataFrame(columns=atributos_tablas_extraccion) #Cree un DataFrame de pandas vacío llamado df con columnas de la variable table_attribs
    tablas = datos.find_all('tbody')# Se Extrae todos los atributos 'tbody' del objeto HTML
    filas = tablas[0].find_all('tr') #Luego se extrae todas las filas de la tabla usando el atributo 'tr'.
    for fila in filas:
        col = fila.find_all('td')
        if len(col)!=0 :
            bank_name = col[1].find_all('a')[1]['title']
            total_assets = col[2].contents[0].replace("\n" , "")
            data_dict = {
                         "Nombre": bank_name,
                         "MC_USD_Billions": total_assets}
            df1 = pd.DataFrame(data_dict, index=[0])
            df = pd.concat([df,df1], ignore_index=True)


    return df

Definiendo la Funcion de Transformacion de los Datos¶

La misma se va a encargar de tomar los datos ya colocados dentro de un DataFrame de Pandas con la tabla extraida y suma 3 columnas nuevas: "MC_USD_Billion", "MC_GBP_Billion", "MC_EUR_Billion", "MC_INR_Billion"

In [8]:
def transformar(df):
    '''Esta función convierte la información del MarkCap de Moneda
    formato a valor flotante, transforma la información del MarkCap de
    USD (Billones) a USD (Millones) redondeando a 2 decimales.
    La función devuelve el marco de datos transformado'''
    df['MC_USD_Billions'] = df['MC_USD_Billions'].str.replace(',','').astype(float)

    exchange_rate = pd.read_csv('exchange_rate.csv')
    exchange_rate['Rate'] = exchange_rate['Rate'].astype(float)
    # Crea las nuevas columnas en el DataFrame
    df['MC_GBP_Billions'] = np.round(df['MC_USD_Billions'] * exchange_rate.loc[exchange_rate['Currency'] == 'GBP', 'Rate'].values[0], 2)
    df['MC_EUR_Billions'] = np.round(df['MC_USD_Billions'] * exchange_rate.loc[exchange_rate['Currency'] == 'EUR', 'Rate'].values[0], 2)
    df['MC_INR_Billions'] = np.round(df['MC_USD_Billions'] * exchange_rate.loc[exchange_rate['Currency'] == 'INR', 'Rate'].values[0], 2)

    return df

Definicion de la Funcion de carga a csv¶

In [9]:
def cargar_a_csv(df, ruta_csv):
    '''Esta función guarda el marco de datos final como un archivo `CSV`
    en la ruta proporcionada.'''

    df.to_csv(ruta_csv) #Utilicé el objeto de función 'to_csv()' para el marco de datos de pandas.
    # fase de combinacion de csvs

Definicion de la Funcion de carga a la Base de Datos¶

In [10]:
def cargar_a_db(df, conexion, nombre_tabla):
    ''' Esta función guarda el marco de datos final como una tabla de base de datos.
    con el nombre proporcionado.'''
    df.to_sql(nombre_tabla , conexion ,if_exists="replace" , index=False)
    #Utilicé el objeto de función 'to_sql()' para el marco de datos de pandas.

Definicion de la Funcion de Consultas a la Base de Datos¶

In [11]:
def consultar(declaraciones_consulta, conexion):
    '''Esta función ejecuta la consulta indicada en la tabla de la base de datos y
    imprime la salida en el terminal.'''

    for declaracion_consulta in declaraciones_consulta:
        print(declaracion_consulta)
        salida_consulta = pd.read_sql(declaracion_consulta, conexion)
        print(salida_consulta)

Fase de creacion del archivo de Log con todos los pasos del Script¶

Contiene ademas, el cierre de la conexion a la base de datos

In [14]:
log_progress('Fase Preliminar Completa. Iniciando el proceso de Extraccion Transformacion y Carga')
df = extraer(url, atributos_tablas_extraccion)
log_progress('Extraccion de Datos Completa. Iniciando el Proceso de Transformacion')
df = transformar(df)
log_progress('Transformacion de los Datos Completa. Iniciando el Proceso de Carga')
cargar_a_csv(df, ruta_csv)
log_progress('Datos Guardados en archivo CSV')
conexion_sql = db3.connect('Banks.db')
log_progress('Conexion a la Base de Datos SQL comenzando .')
cargar_a_db(df, conexion, nombre_tabla)
log_progress('Datos cargados en la base de datos como tabla. Ejecutando la consulta')
consultas= [
    "SELECT * FROM Largest_banks ",
    "SELECT AVG(MC_GBP_Billions) FROM Largest_banks",
    "SELECT Nombre from Largest_banks LIMIT 5"
]
consultar(consultas, conexion)
log_progress('Proceso ETL Completo!.')
conexion.close()
SELECT * FROM Largest_banks 
                                    Nombre  MC_USD_Billions  MC_GBP_Billions  \
0                           JPMorgan Chase           432.92           346.34   
1                          Bank of America           231.52           185.22   
2  Industrial and Commercial Bank of China           194.56           155.65   
3               Agricultural Bank of China           160.68           128.54   
4                                HDFC Bank           157.91           126.33   
5                              Wells Fargo           155.87           124.70   
6                                     HSBC           148.90           119.12   
7                           Morgan Stanley           140.83           112.66   
8                  China Construction Bank           139.82           111.86   
9                            Bank of China           136.81           109.45   

   MC_EUR_Billions  MC_INR_Billions  
0           402.62         35910.71  
1           215.31         19204.58  
2           180.94         16138.75  
3           149.43         13328.41  
4           146.86         13098.63  
5           144.96         12929.42  
6           138.48         12351.26  
7           130.97         11681.85  
8           130.03         11598.07  
9           127.23         11348.39  
SELECT AVG(MC_GBP_Billions) FROM Largest_banks
   AVG(MC_GBP_Billions)
0               151.987
SELECT Nombre from Largest_banks LIMIT 5
                                    Nombre
0                           JPMorgan Chase
1                          Bank of America
2  Industrial and Commercial Bank of China
3               Agricultural Bank of China
4                                HDFC Bank