Daiana Grimi - TP Final Integrador - CaC #22041 - Big Data
# A veces necesitamos instalar nuevas librerías en nuestros proyectos
!pip install openpyxl==3.0.10
# imports
import numpy as np
import pandas as pd
import sqlite3 as sql3 # para poder leer la articles.db
import openpyxl # para que levante el excel
import matplotlib.pyplot as plt #para graficar series
import seaborn as sns #para graficar data frame
# Levanto los datos en 3 diferentes dataframes
# convierto los archivos en dataframes, siempre que se pueda
# Comenzamos con el .db que es el más complicado de interpretar
# Debemos realizar una consulta para poder obtener los datos
#Articulos
conn = sql3.connect('/work/data/articles.db')
sql_query = pd.read_sql_query('SELECT * FROM articles', conn)
#filtro solamente las columnas que me interesan
df_articles = pd.DataFrame(sql_query, columns = ['article_id','article_name','unit_price'])
# Vendedores, me quedo solamente con el nombre del vendedor
df_sellers = pd.read_excel('/work/data/sellers.xlsx', index_col=0)
# Ordenes
df_orders = pd.read_csv('/work/data/orders.csv')
# Exploración del df de artículos
print('Muestra de datos del dataframe correspondiente a Artículos')
print('\nDataframe Artículos')
print(df_articles.head())
print('\nDimensión del dataframe :', df_articles.shape[0], 'filas y ', df_articles.shape[1], 'columnas' )
print('\nBúsqueda de valores nulos por columna')
print(df_articles.isnull().sum())
print('\nTipo de datos por columna')
print(df_articles.dtypes)
# Exploración del df de vendedores
print('Muestra de datos del dataframe correspondiente a Vendedores')
print('\nDataframe Vendedores')
print(df_sellers.head())
print('\nDimensión del dataframe :', df_sellers.shape[0], 'filas y ', df_sellers.shape[1], 'columnas' )
print('\nBúsqueda de valores nulos por columna')
print(df_sellers.isnull().sum())
print('\nTipo de datos por columna')
print(df_sellers.dtypes)
# Exploración del df de órdenes
print('Muestra de datos del dataframe correspondiente a Órdenes')
print('\nDataframe Órdenes')
print(df_orders.head())
print('\nDimensión del dataframe :', df_orders.shape[0], 'filas y ', df_orders.shape[1], 'columnas' )
print('\nBusqueda de valores nulos por columna')
print(df_orders.isnull().sum())
print('\nTipo de datos por columna')
print(df_orders.dtypes)
# En esta etapa debemos realizar la conversión necesaria de los datos, filtrar columnas, eliminar ids o asignar los mismos a una columna en particular
# además se preparan los datos que se observaron en el paso anterior
# Convertimos a la columna unit_price en un dato de tipo float
df_articles['unit_price'] = df_articles['unit_price'].astype(float)
print(df_articles.dtypes)
# Vamos a crear datos nuevos, a partir de los datos de otros dataframes
# Copio los datos de las ordenes
dg_df = df_orders.copy()
# Cambio el indice del df de articulos, en un nuevo dataframe
df_articles2 = df_articles.set_index('article_id',inplace=False)
#En df_articles2, voy a asignar a las columnas article_name y total_amount el valor de article_id y para seller_name el valor de seller_id
dg_df = dg_df.assign(article_name = dg_df['article_id'])
dg_df = dg_df.assign(total_amount = dg_df['article_id'])
dg_df = dg_df.assign(seller_name = dg_df['seller_id'])
#reemplazo los valores en el nuevo dataframe(dg_df)
for i in range(len(dg_df.index)):
# obtenemos el id del artículo
id_articulo = dg_df.loc[i]['article_id']
# Guardo en un string el nombre del artículo
nombreArticulo = df_articles2.loc[id_articulo]['article_name']
# lo asigno a la columna correspondiente
dg_df.loc[i,'article_name'] = nombreArticulo
# Obtenemos total_amount
precioArticulo = df_articles2.loc[id_articulo]['unit_price']
dg_df.loc[i,'total_amount'] = dg_df.loc[i,'quantity'] * precioArticulo
# Obtenemos el id del vendedor, asignamos el nombre a una variable y lo asignamos en dg_df
id_vendedor = dg_df.loc[i]['seller_id']
nombreVendedor = df_sellers.loc[id_vendedor]['seller_name']
dg_df.loc[i, 'seller_name'] = nombreVendedor
# elimino las columnas que no necesito -- Es destructivo, ya que el parámetro inplace=True
dg_df.drop(['order_id','article_id','seller_id'], axis='columns', inplace=True)
# RESOLUCIÓN ANALÍTICA
# Creo un nuevo dataframe para responder a esta pregunta, en donde voy a agrupar por article_name
# y voy a sumar las cantidades. Obtengo el primer elemento y lo muestro
df_sum_articulos = dg_df.groupby('article_name').sum()
df_sum_articulos_ord = df_sum_articulos.sort_values('quantity',ascending=False)
df_cant_mas_vendido = df_sum_articulos_ord['quantity'].head(1)
df_art_mas_vendido = df_cant_mas_vendido.index[0]
print('El artículo más vendido es',df_art_mas_vendido, 'y la cantidad vendida es',df_cant_mas_vendido[0],'unidades.')
# RESOLUCIÓN GRÁFICA
# Obtengo los primeros 5 artículos de la lista de más vendidos
df_art_primeros_ord = df_sum_articulos_ord['quantity'].head(5)
# Obtengo los últimos 5 artículos de la lista de más vendidos
df_art_ultimos_ord = df_sum_articulos_ord['quantity'].tail(5)
# Obtengo un nuevo dataframe para mostrar las diferencias entre los primeros 5 y los últimos 5 en unidades vendidas
df_graf_articulos = pd.concat([df_art_primeros_ord, df_art_ultimos_ord])
plt.figure(figsize=(8,4), dpi=100)
sns.barplot(y = df_graf_articulos, x = df_graf_articulos.index)
plt.xticks(rotation=45,ha='right')
plt.xlabel("Artículo", size = 13)
plt.ylabel("Cantidad vendida", size = 13)
plt.title("5 Artículos más y menos vendidos",
fontdict={'family': 'serif',
'color' : 'darkblue',
'weight': 'bold',
'size': 14})
plt.show()
# RESOLUCIÓN ANALÍTICA
# Creo un nuevo dataframe para responder a la pregunta, agrupando por article_name
# Sumo los valores de total_amount por cada article_name en forma descendiente
# Obtengo los primeros 5
df_sum_ventas = dg_df.groupby('article_name').sum()
df_sum_ventas_ord = df_sum_ventas.sort_values('total_amount',ascending=False).head(5)
df_cant_mayor_ingresos = df_sum_ventas_ord['total_amount'].head(1)
df_art_mayor_ingresos = df_cant_mayor_ingresos.index[0]
df_cant_mayor_ingresos = round(df_cant_mayor_ingresos,2)
# Suponemos que los montos están expresados en USD, por lo que agregamos esa moneda en el mensaje que mostramos
print('EL artículo que más ingresos nos proporcionó fue',df_art_mayor_ingresos, 'con ingresos de USD', df_cant_mayor_ingresos[0])
# RESOLUCIÓN GRÁFICA
plt.figure(figsize=(8,4), dpi=100)
sns.barplot(x = df_sum_ventas_ord.index, y = df_sum_ventas_ord['total_amount'])
plt.xlabel("Artículo", size = 13)
plt.ylabel("Ingresos (USD)", size = 13)
plt.title("Los 5 artículos que más ingresos generaron",
fontdict={'family': 'serif',
'color' : 'darkblue',
'weight': 'bold',
'size': 14})
plt.show()
# RESOLUCIÓN ANALÍTICA
df_sum_vendedor = dg_df.groupby('seller_name').sum()
df_sum_vendedor_ord = df_sum_vendedor.sort_values('total_amount',ascending=False)
df_mayor_vendedor = df_sum_vendedor_ord[['quantity']+['total_amount']].head(1)
print('El vendedor al que debe otorgarse el bono por "Mejor Vendedor del mes" es:',df_mayor_vendedor.index[0],'.\nVendió un total de',df_mayor_vendedor.quantity[0],'unidades y los ingresos correspondientes a sus ventas fueron de USD', round(df_mayor_vendedor.total_amount[0],2))
# RESOLUCIÓN GRÁFICA
plt.figure(figsize=(8,4), dpi=100)
sns.barplot(x=df_sum_vendedor_ord.index,y=df_sum_vendedor_ord['total_amount'])
plt.xticks(rotation=45,ha='right')
plt.xlabel("Vendedor", size = 13)
plt.ylabel("Ingresos (USD)", size = 13)
plt.title("Monto de ingresos por vendedor",
fontdict={'family': 'serif',
'color' : 'darkblue',
'weight': 'bold',
'size': 14})
plt.show()
# RESOLUCIÓN ANALÍTICA
df_venta_semanal = dg_df.groupby(by='week').sum().sort_values('total_amount',ascending=False)
print('Analizando los valores obtenidos, creemos que debería lanzar una campaña de promociones en la semana número',df_venta_semanal.index[2],'\npara intenar compensar los 2 últimos períodos de baja en ventas y repuntar las ventas de la semana número',df_venta_semanal.index[3],'.')
# RESOLUCIÓN GRÁFICA
plt.figure(figsize=(8,4), dpi=100)
sns.barplot(x = df_venta_semanal.index,y = df_venta_semanal['total_amount'])
plt.xlabel("Semana", size = 13,)
plt.ylabel("Ingresos (USD)", size = 13)
plt.title("Monto de ingresos por semana",
fontdict={'family': 'serif',
'color' : 'darkblue',
'weight': 'bold',
'size': 14})
plt.show()
df_ventas_semanal=dg_df.copy()
sns.catplot(x="week", y="total_amount", data=df_ventas_semanal)
plt.xlabel("Semana", size = 12,)
plt.ylabel("Ingresos (USD)", size = 12)
plt.title("Monto de ingresos por semana",
fontdict={'family': 'serif',
'color' : 'darkblue',
'weight': 'bold',
'size': 14})
plt.show()
# RESOLUCIÓN
# Creo un nuevo dataframe para responder a la pregunta, agrupando por country_name
# Ordenamos por los valores de total_amount por cada country_name en forma descendiente
# Obtengo el primero, y lo muestro
df_sum_ventas_pais = dg_df.groupby('country_name').sum()
df_sum_ventas_pais_ord = df_sum_ventas_pais.sort_values('total_amount',ascending=False)
df_pais_mayor_ingresos = df_sum_ventas_pais_ord['total_amount'].head(1)
df_row_mayor_ingresos = df_pais_mayor_ingresos.index[0]
df_pais_mayor_ingresos = round(df_pais_mayor_ingresos,2)
# Suponemos que los montos están expresados en USD, por lo que agregamos esa moneda en el mensaje que mostramos
print('El país que más ingresos nos proporcionó fue',df_row_mayor_ingresos, 'con ingresos de USD', df_pais_mayor_ingresos[0])
# Gráfica por países, ordenados de mayor a menor cantidad de ingresos
plt.figure(figsize=(8,4), dpi=100)
sns.barplot(x = df_sum_ventas_pais_ord.index,y = df_sum_ventas_pais_ord['total_amount'])
plt.xticks(rotation=45,ha='right')
plt.xlabel("País", size = 13,)
plt.ylabel("Ingresos (USD)", size = 13)
plt.title("Ingresos por país",
fontdict={'family': 'serif',
'color' : 'darkblue',
'weight': 'bold',
'size': 14})
plt.show()
# RESOLUCIÓN
# Creo un nuevo dataframe para responder a la pregunta, agrupando por country_name y contando la cantidad de registros para cada uno
# Ordenamos los valores por cada country_name en forma descendiente
# Obtengo el primero, y lo muestro
df_count_vende_pais = dg_df.groupby('country_name').count()
df_count_vende_pais_ord = df_count_vende_pais.sort_values('total_amount',ascending=False)
df_pais_mayor_vend = df_count_vende_pais_ord['total_amount'].head(1)
df_row_mayor_ingresos = df_pais_mayor_vend.index[0]
df_pais_mayor_vend = round(df_pais_mayor_vend,2)
# Mostramos el país que maás ventas realizó y el total de ventas realizadas por el mismo
print('El país que más ventas realizó fue',df_row_mayor_ingresos, 'con', df_pais_mayor_vend[0],'ventas.')
# Gráfica por países, ordenados de mayor a menor cantidad de ventas
plt.figure(figsize=(8,4), dpi=100)
sns.barplot(x = df_count_vende_pais_ord.index, y = df_count_vende_pais_ord['total_amount'])
plt.xticks(rotation=45,ha='right')
plt.xlabel("País", size = 13,)
plt.ylabel("Cantidad de Ventas", size = 13)
plt.title("Cantidad de Ventas por país",
fontdict={'family': 'serif',
'color' : 'darkblue',
'weight': 'bold',
'size': 14})
plt.show()
# RESOLUCIÓN
# Creo un nuevo dataframe para responder a la pregunta, copiando las columnas country_name, seller_name y total_amount
# Agrupamos por country_name y seller_name
# Creamos una tabla pivot para mostrar los valores agrupados
# Reèmplazamos los valores NaN por 0
df_preg7 = dg_df[['country_name','seller_name','total_amount']]
df_preg7_ord = df_preg7.groupby(['country_name','seller_name'],as_index=False).sum()
df_pivot7= df_preg7_ord.pivot(index='country_name',columns='seller_name')
df_pivot7 = df_pivot7.fillna(0)
# Agregamos parámetros a la gráfica del mapa de calor
fig, ax= plt.subplots()
im = ax.pcolor(df_pivot7)
#label names
row_labels = df_pivot7.columns.levels[1]
col_labels = df_pivot7.index
#move ticks and labels to the center
ax.set_xticks(np.arange(df_pivot7.shape[1])+ 0.5, minor=False)
ax.set_yticks(np.arange(df_pivot7.shape[0])+ 0.5, minor=False)
#insert labels
ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(col_labels, minor=False)
# Gráfica de mapa de calor, con información referida a los ingresos por ventas de cada vendedor por cada país
plt.pcolor(df_pivot7)
plt.colorbar()
plt.xticks(rotation=90)
plt.xlabel("Vendedor", size = 13,)
plt.ylabel("País", size = 13)
plt.title("Ingresos por Vendedores por país",
fontdict={'family': 'serif',
'color' : 'darkblue',
'weight': 'bold',
'size': 14})
plt.show()