!pip install openpyxl==3.0.10
import numpy as np
import pandas as pd
import sqlite3 as sql3
import openpyxl
import matplotlib.pyplot as plt
import seaborn as sns
# Artículos (.db)
conn = sql3.connect('/work/data/articles.db')
sql_query = pd.read_sql_query('SELECT * FROM articles', conn)
df_articles = pd.DataFrame(sql_query, columns = ['article_id', 'article_name', 'unit_price'])
# Vendedores (.xlsx)
df_sellers = pd.read_excel('/work/data/sellers.xlsx', index_col=0)
# Órdenes (.csv)
df_orders = pd.read_csv('/work/data/orders.csv')
# Exploración "Artículos"
print('Muestra de datos')
print(df_articles.head())
print('\nFormato del dataframe')
print(df_articles.shape)
print('\nBúsqueda de valores nulos por columna')
print(df_articles.isnull().sum())
print('\nFormato de los datos por columna')
print(df_articles.dtypes)
# Exploración "Vendedores"
print('Muestra de datos')
print(df_sellers.head())
print('\nFormato del dataframe')
print(df_sellers.shape)
print('\nBúsqueda de valores nulos por columna')
print(df_sellers.isnull().sum())
print('\nFormato de los datos por columna')
print(df_sellers.dtypes)
# Exploración "Órdenes"
print('Muestra de datos')
print(df_orders.head())
print('\nFormato del dataframe')
print(df_orders.shape)
print('\nBúsqueda de valores nulos por columna')
print(df_orders.isnull().sum())
print('\nFormato de los datos por columna')
print(df_orders.dtypes)
df_articles['unit_price'] = df_articles['unit_price'].astype(float)
print(df_articles.dtypes)
# Copia del df_orders
my_df = df_orders.copy()
# Columna de Id se vuelve el índice del df "Artículos"
df_articles.set_index('article_id',inplace = True)
# Agregado de columnas "article_name", "total_amount" y "seller_name" con sus Id
my_df = my_df.assign(article_name = my_df['article_id'])
my_df = my_df.assign(total_amount = my_df['article_id'])
my_df = my_df.assign(seller_name = my_df['seller_id'])
# Reemplazo los Id con los valores deseados (nombre de artículo, precio*cantidad, nombre de vendedor)
for i in range(len(my_df.index)): # Utilizo el número de registro
# Nombre de artículo (en dos pasos, con variable):
# Generación de variable de guardado del nombre del artículo extraído del df "Artículos"
article = df_articles.loc[my_df.loc[i]['article_id']]['article_name']
# Asignación del nombre extraído a la columna correspondiente
my_df.loc[i,'article_name'] = article
# Precio * Cantidad (en un paso, sin variable)
my_df.loc[i,'total_amount'] = my_df.loc[i,'quantity'] * df_articles.loc[my_df.loc[i]['article_id']]['unit_price']
# Nombre de vendedor (en un paso, sin variable)
my_df.loc[i,'seller_name'] = df_sellers.loc[my_df.loc[i]['seller_id']]['seller_name']
# Eliminación de columnas innecesarias
my_df.drop(['order_id', 'article_id', 'seller_id'], axis = 'columns', inplace=True)
print(my_df)
# RESOLUCIÓN ANALÍTICA
# Df con agrupamiento por "Artículo", y ordenado de mayor a menor por "Cantidad".
df1=my_df.groupby('article_name').sum().sort_values('quantity',ascending=False)
# Df donde con los 10 artículos más vendidos por cantidad.
df1_10 = df1.head(10)
# Impresión del artículo más vendido por cantidad.
print(df1['quantity'].head(1))
# Respuesta
print("\nRespuesta: El artículo más vendido en unidades es",df1.index[0],"con",df1['quantity'][0],"unidades.")
# RESOLUCIÓN GRÁFICA
# 5 artículos más vendidos (por unidades)
grafico1 = sns.barplot(x=df1.head(5).index,y=df1.head(5)["quantity"])
grafico1.set_xlabel("Artículo")
grafico1.set_ylabel("Unidades vendidas")
grafico1.set_title("GRÁFICO 1 - 5 artículos más vendidos (por unidades)")
plt.show()
# RESOLUCIÓN ANALÍTICA
# Df con agrupamiento por "Artículo", y ordenado de mayor a menor por "Total de ventas", limitado a los 10 mayores.
df2 = (my_df.groupby('article_name').sum()).sort_values('total_amount',ascending=False).head(10)
# Impresión de los 10 artículos más vendidos por total de ventas.
print(df2['total_amount'])
# Respuesta
print("\nRespuesta: El artículo más vendido por montos de ventas es",df2.index[0],"con un total de ventas de $","{:.2f}".format(df2['total_amount'][0]),".")
# RESOLUCIÓN GRÁFICA
# 5 artículos más vendidos (por ingresos)
grafico2 = sns.barplot(x=df2.head().index,y=df2.head()['total_amount'])
grafico2.set_xlabel("Artículo")
grafico2.set_ylabel("Total vendido")
grafico2.set_title("GRÁFICO 2 - 5 artículos más vendidos (por ingresos)")
plt.show()
# RESOLUCIÓN ANALÍTICA
# Df con agrupamiento por "Vendedor", y ordenado de mayor a menor por "Total de ventas".
df3 = (my_df.groupby('seller_name').sum()).sort_values('total_amount',ascending=False)
df3a = (my_df.groupby('seller_name').sum()).sort_values('quantity',ascending=False)
# Impresión de los vendedores con más valor de ventas, junto a sus unidades vendidas.
print(df3[['total_amount'] +['quantity']])
print()
print(df3a[['quantity'] +['total_amount']])
# Respuesta
print("\nRespuesta: Le entregaría el bono a" ,df3.index[0],"por ser el vendedor que más ingresos por ventas ha producido, con un total de ventas de $","{:.2f}".format(df3['total_amount'][0]),", además de la mayor cantidad de unidades vendidas.")
# RESOLUCIÓN GRÁFICA
# Mejores 5 vendedores (por totales de venta)
grafico3 = sns.barplot(x=df3.head(5).index, y=df3.head(5)["total_amount"])
grafico3.set_xlabel("Vendedor")
grafico3.set_ylabel("Total vendido")
grafico3.set_title("GRÁFICO 3.A - Mejores 5 vendedores (por totales de venta)")
plt.xticks(rotation=60)
plt.show()
# Mejores 5 vendedores (por unidades)
grafico3a = sns.barplot(x=df3a.head(5).index, y=df3a.head(5)["quantity"])
grafico3a.set_xlabel("Vendedor")
grafico3a.set_ylabel("Unidades vendidas")
grafico3a.set_title("GRÁFICO 3.B - Mejores 5 vendedores (por unidades)")
plt.xticks(rotation=60)
plt.show()
# RESOLUCIÓN ANALÍTICA
# Df con agrupamiento por "Semana", y ordenado de mayor a menor por "Total de ventas".
df4 = (my_df.groupby('week').sum()).sort_values('total_amount',ascending=False)
# Impresión de las semanas con mayor total de ventas.
print(df4['total_amount'])
media = df4['total_amount'].mean()
# Impresión del total de ventas promedio por semana.
print("\nTotal de ventas promedio por semana: $", "{:.2f}".format(media))
diferencia_ultima_semana = media - df4['total_amount'][4]
# Respuesta
print("\nRespuesta: Existe una tendencia de ventas decrecientes a lo largo de las semanas. Lanzaría una campaña de promociones en la tercera y la cuarta semana, dado que las ventas totales en estas semanas están por debajo del promedio ($","{:.2f}".format(media),"), con especial énfasis en la última semana que presenta el valor de ventas más bajo, $","{:.2f}".format(diferencia_ultima_semana),"por debajo del promedio.")
# RESOLUCIÓN GRÁFICA
# Ventas por semana
grafico4 = sns.barplot(x=df4.index, y=df4["total_amount"])
grafico4.set_xlabel("Semana")
grafico4.set_ylabel("Total vendido")
grafico4.set_title("GRÁFICO 4 - Ventas por semana")
plt.show()
# RESOLUCIÓN ANALÍTICA
# Df con agrupamiento por "País", y ordenado de mayor a menor por "Cantidad".
df5 = (my_df.groupby('country_name').sum()).sort_values('quantity',ascending=False)
# Impresión de los 5 países con mayor cantidad de ventas por unidades.
print(df5['quantity'].head(5))
cantidad_mejor_pais = df5['quantity'][0]
cantidad_mejor_pais2 = df5['quantity'][1]
# Respuesta
print("\nRespuesta: El país que más unidades ha comprado es" ,df5.index[0],"con un total de",cantidad_mejor_pais,"unidades compradas;",cantidad_mejor_pais-cantidad_mejor_pais2,"unidades más que las del segundo país que más unidades compró (",df5.index[1],"con",cantidad_mejor_pais2,"unidades).")
# RESOLUCIÓN GRÁFICA
# 5 paises que más compran (en unidades)
grafico5 = sns.barplot(x=df5.head(5).index, y=df5["quantity"].head(5))
grafico5.set_xlabel("Países")
grafico5.set_ylabel("Unidades")
grafico5.set_title("GRÁFICO 5 - 5 paises que más compran (en unidades)")
plt.show()
# RESOLUCIÓN ANALÍTICA
# Df con agrupamiento por "País", y ordenado de mayor a menor por "Total de ventas".
df6 = (my_df.groupby('country_name').sum()).sort_values('total_amount',ascending=False)
# Impresión de los 5 países con mayor total de ventas.
print(df6['total_amount'].head(5))
total_mejor_pais = df6['total_amount'][0]
total_mejor_pais2 = df6['total_amount'][1]
# Respuesta
print("\nRespuesta: El país que más valor de compras posee es" ,df6.index[0],"con un total de compras de $","{:.2f}".format(total_mejor_pais),"; $","{:.2f}".format(total_mejor_pais-total_mejor_pais2),"de compras más que las del segundo país que más compró (",df6.index[1],"con $","{:.2f}".format(total_mejor_pais2),").")
# RESOLUCIÓN GRÁFICA
# 5 paises que más compran (en totales de compra)
grafico6 = sns.barplot(x=df6.head(5).index, y=df6["total_amount"].head(5))
grafico6.set_xlabel("Países")
grafico6.set_ylabel("Total de compra")
grafico6.set_title("GRÁFICO 6 - 5 paises que más compran (en totales de compra)")
plt.show()
# RESOLUCIÓN ANALÍTICA
# Df con agrupamiento por "Vendedor" y "Semana", junto con su "Total de ventas".
df7indice = (my_df.groupby(['seller_name','week'])).sum()[['total_amount']]
df7 = df7indice.reset_index()
print(df7indice)
# Respuesta
print("\nRespuesta: Si bien los totales de ventas por semana muestran una tendencia clara a la disminución de las ventas a lo largo de las semanas (ver gráfico 4), esto no se ve reflejado cuando se discriminan las ventas por vendedor.")
# RESOLUCIÓN GRÁFICA
grafico7a = sns.barplot(x=df7['seller_name'].head(32), y=df7["total_amount"], hue=df7['week'])
grafico7a.set_xlabel("Vendedores")
plt.xticks(rotation=90)
grafico7a.set_ylabel("Total de compra")
grafico7a.set_title("GRÁFICO 7.A - Total de ventas de cada vendedor por semana (vendedores 1-8 de 15)")
plt.show()
grafico7b = sns.barplot(x=df7['seller_name'].tail(28), y=df7["total_amount"], hue=df7['week'])
grafico7b.set_xlabel("Vendedores")
plt.xticks(rotation=90)
grafico7b.set_ylabel("Total de compra")
grafico7b.set_title("GRÁFICO 7.B - Total de ventas de cada vendedor por semana (vendedores 9-15 de 15)")
plt.show()