# Instalación de dependencias necesarias
!pip install openpyxl==3.0.10 #para que pueda leer correctamente el archivo .xlsx
# Importación de librerías usadas
import numpy as np
import pandas as pd
import sqlite3 as sql3
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import rcParams
conn = sql3.connect('/work/data/articles.db')
# Se toma la columna article_id como index del DataFrame y como el método read_sql_query no la elimina,
# hago un drop de esa columna posterior, ya que quedan todos NaN y no tiene opción inplace.
sql_query = pd.read_sql_query('SELECT * FROM articles', conn, index_col='article_id')
df_articles = pd.DataFrame(sql_query, columns= ['article_id','article_name','unit_price'])
df_articles = df_articles.drop('article_id', axis=1)
# Aprovecho a ver una muestra de esos datos y ver si se importó correctamente.
print(df_articles.head(2))
# Se toma la columna seller_id como index del DataFrame
df_sellers = pd.read_excel('/work/data/sellers.xlsx', index_col='seller_id')
# Aprovecho a ver una muestra de esos datos y ver si se importó correctamente.
print(df_sellers.head(2))
df_orders = pd.read_csv('/work/data/orders.csv')
#Aprovecho a ver una muestra de esos datos y ver si se importó correctamente.
print(df_orders.head(2))
print('Muestra de datos')
print(df_articles.sample())
print('Dimensión del DataFrame')
print(df_articles.shape)
print('Búsqueda de valores nulos')
print(df_articles.isnull().sum())
print('Tipo de dato por columna')
print(df_articles.dtypes)
print('Muestra de datos')
print(df_sellers.sample())
print('Dimensión del dataframe')
print(df_sellers.shape)
print('Búsqueda de valores nulos')
print(df_sellers.isnull().sum())
print('Tipo de dato por columna')
print(df_sellers.dtypes)
print('Muestra de datos')
print(df_orders.sample())
print('Dimensión del dataframe')
print(df_orders.shape)
print('Búsqueda de valores nulos')
print(df_orders.isnull().sum())
print('Tipo de dato por columna')
print(df_orders.dtypes)
pd.options.display.float_format = '$ {:,.2f}'.format
df_articles['unit_price'] = df_articles['unit_price'].astype(float)
print(df_articles.dtypes)
print(df_articles.head(3))
data = df_orders.copy()
data.head(2)
data_article = data.merge(df_articles, left_on='article_id', right_on=df_articles.index, how='inner')
data_article.head(3)
data_article_seller = data_article.merge(df_sellers, left_on='seller_id', right_on=df_sellers.index, how='inner')
data_article_seller.head(3)
data_unificada = data_article_seller.drop(['article_id','seller_id'], axis=1)
data_unificada.head(3)
data_unificada['total_amount'] = data_unificada['quantity'] * data_unificada['unit_price']
data_unificada.head(3)
data_a_trabajar = data_unificada.drop(['unit_price','order_id'], axis=1)
data_a_trabajar.head(3)
data_a_trabajar.dtypes
group_vendidos = data_a_trabajar.groupby('article_name').sum().sort_values('quantity', ascending=False)
mas_vendido = group_vendidos.loc[:,'quantity'].head(1).index[0]
mas_vendido_cantidad = group_vendidos.loc[:,'quantity'].head(1)[0]
print("El artículo más vendido es", mas_vendido, "con", mas_vendido_cantidad, "unidades vendidas.")
rcParams['figure.figsize'] = 18,7
ax = sns.barplot(data=group_vendidos, x=group_vendidos.index, y='quantity', palette='muted')
ax.set_xlabel('\nArtículo', fontsize = 15)
ax.set_ylabel('Cantidad\n', fontsize = 15)
plt.xticks(rotation=30)
plt.title('Artículo más vendido (en cantidad)\n', fontsize=20)
ax.tick_params(axis='both' , labelsize=10)
plt.show()
group_ingresos = data_a_trabajar.groupby('article_name').sum().sort_values('total_amount', ascending=False)
mas_ingresos = group_ingresos.loc[:,'total_amount'].head(1).index[0]
mas_ingresos_cantidad = round(group_ingresos.loc[:,'total_amount'].head(1)[0],2)
print("El artículo que generó mayor ingreso es", mas_ingresos, "por un monto de $", mas_ingresos_cantidad)
cat_principales = group_ingresos[group_ingresos['total_amount'] > 50000]['total_amount']
cat_menores = group_ingresos[group_ingresos['total_amount'] < 50000]['total_amount'].sum()
cat_menores = pd.Series(cat_menores, index=['Otros'])
amount_plot = pd.concat([cat_principales,cat_menores])
print('Cuatro componentes que más generaron ingresos y el último agrupado todos los demás')
amount_plot
rcParams['figure.figsize'] = 6, 6
explode = (0.2,0,0,0,0)
total = amount_plot.sum()
plt.title('Artículos que mayores ingresos generaron', fontsize=20)
plt.pie(x=amount_plot, labels=amount_plot.index, colors=sns.color_palette('muted'), explode=explode, startangle=120, textprops={'fontsize': 12}, autopct = lambda p: '$ {:,.2f}'.format(p * total / 100))
plt.show()
group_bono = data_a_trabajar.groupby('seller_name').sum().sort_values('total_amount', ascending=False)
mejor_vendedor = group_bono.head(1).index[0]
mejor_vendedor_monto = round(group_bono.head(1)['total_amount'].values[0],2)
print("El vendedor que más vendio en el mes es", mejor_vendedor, "por un monto de $", mejor_vendedor_monto)
rcParams['figure.figsize'] = 18,7
ax = sns.barplot(data=group_bono, x=group_bono.index, y='total_amount', palette='muted')
ax.set_xlabel('Vendedor', fontsize = 15)
ax.set_ylabel('Monto vendido\n', fontsize = 15)
plt.xticks(rotation=30)
plt.title('Monto vendido por cada vendedor\n', fontsize=20)
ax.tick_params(axis='both' , labelsize=13)
plt.show()
group_variacion = data_a_trabajar.groupby('week').sum().sort_values('total_amount', ascending=False)
print(group_variacion['total_amount'])
maximo_mensual = group_variacion['total_amount'].max()
#tengo que cambiar la configuración de formato de los float para que los muestre como %
pd.options.display.float_format = '% {:,.2f}'.format
(group_variacion['total_amount'] / maximo_mensual) - 1
# RESOLUCIÓN GRÁFICA
rcParams['figure.figsize'] = 6,5
#gráfico de barras
ax = sns.barplot(data=group_variacion, x=group_variacion.index, y='total_amount', palette='muted')
ax.set_xlabel('Semana', fontsize = 15)
ax.set_ylabel('Monto vendido\n', fontsize = 15)
ax.set_label('Label via method')
# gráfico de línea de tendencia
ax = plt.scatter(group_variacion.index, group_variacion['total_amount'], marker='None')
z = np.polyfit(group_variacion.index, group_variacion['total_amount'], 1)
p = np.poly1d(z)
plt.plot(group_variacion.index-1, p(group_variacion.index),"r--", linewidth=3, label='Tendencia')
plt.legend()
plt.title('Monto vendido por semana y tendencia\n', fontsize=20)
plt.show()
#vuelvo a configurar el formato $ para todos los float
pd.options.display.float_format = '$ {:,.2f}'.format
group_pais = data_a_trabajar.groupby('country_name').sum().sort_values('total_amount', ascending=False)
print(group_pais[['quantity','total_amount']])
ingreso_unitario_por_pais = (group_pais['total_amount'] / group_pais['quantity']).sort_values(ascending=False)
print("El país que mayor ingresos generó fue", ingreso_unitario_por_pais.index[0], "por un monto unitario de $", round(ingreso_unitario_por_pais[0],2))
rcParams['figure.figsize'] = 12,6
ax1 = sns.barplot(data=group_pais, x=group_pais.index, y='total_amount', palette='muted')
plt.xticks(rotation=30)
ax2 = ax1.twinx()
ax2 = sns.lineplot(data=group_pais, x=group_pais.index, y='quantity', color='darkblue', linewidth=3, ax=ax2, label='Cantidad')
ax1.set_xlabel('\nPaís', fontsize = 15)
ax1.set_ylabel('Monto vendido\n', fontsize = 15)
ax2.set_ylabel('\nCantidad vendida', fontsize = 15)
ax1.tick_params(axis='both' , labelsize=13)
ax2.tick_params(axis='both' , labelsize=13)
plt.title('Monto y cantidad por país\n', fontsize=20)
plt.show()
#preparar los datos para poder mostrarlos correctamente en el gráfico
ingreso_unitario_por_pais.reset_index
ing_unitario_graf = ingreso_unitario_por_pais.to_frame()
ing_unitario_graf = ing_unitario_graf.rename(columns={0:'Monto_unitario'})
rcParams['figure.figsize'] = 15,8
ax = sns.barplot(data=ing_unitario_graf , y=ing_unitario_graf .index, x=ing_unitario_graf.Monto_unitario, orient='h', palette='muted')
ax.set_xlabel('Ingreso unitario', fontsize = 15)
ax.set_ylabel('País\n', fontsize = 15)
ax.axvline(x=ing_unitario_graf.mean()[0], color='orange', linewidth=3, label='Promedio')
ax.axvline(x=(ing_unitario_graf.mean() + 2 * ing_unitario_graf.std())[0], color='darkblue', linewidth=3, label='Promedio + 2 desvíos standard')
ax.tick_params(axis='both', labelsize=13)
plt.legend()
plt.title('Ingreso unitario por país\n', fontsize=20)
plt.show()
contador = data_a_trabajar['quantity'].value_counts()
contador_df = contador.to_frame().reset_index()
contador_df = contador_df.rename(columns={"index":"Cantidad_por_pedido","quantity":"Repeticiones"})
contador_df = contador_df.sort_values('Cantidad_por_pedido', ascending=True)
contador_df = contador_df.reset_index(drop=True)
print(contador_df.sort_values('Cantidad_por_pedido', ascending=True))
rcParams['figure.figsize'] = 10,5
ax = sns.histplot(data=data_a_trabajar, x='quantity', kde=True, bins=data_a_trabajar.quantity.max())
ax.set_xlabel('Cantidad vendida por pedido\n', fontsize = 15)
ax.set_ylabel('Repeticiones / frecuencia\n', fontsize = 15)
ax.tick_params(axis='both' , labelsize=13)
eje_x = np.arange(data_a_trabajar.quantity.min(), data_a_trabajar.quantity.max()+1, 1)
plt.xticks(eje_x)
plt.title('Distribución de artículos vendidos por cada pedido\n', fontsize=20)
plt.show()
lista_mejores_tres = data_a_trabajar.groupby('seller_name').sum().sort_values('total_amount',ascending=False).head(3).index.to_list()
extracto_solo_mejores_tres = data_a_trabajar[data_a_trabajar['seller_name'].isin(lista_mejores_tres)]
para_graficar = extracto_solo_mejores_tres.groupby(['country_name','seller_name']).count()
para_graficar = para_graficar.reset_index()
para_graficar.loc[:,['seller_name','country_name','quantity']]
rcParams['figure.figsize'] = 15,8
ax = sns.barplot(data=para_graficar, x='country_name', y='quantity', hue='seller_name', palette='muted')
ax.set_xlabel('\nVendedor', fontsize = 15)
ax.set_ylabel('Cantidad vendida\n', fontsize = 15)
ax.tick_params(axis='both' , labelsize=13)
plt.title('Cantidad vendida por país de los 3 mejores vendedores\n', fontsize=20)
plt.legend(title='País')
plt.xticks(rotation=30)
plt.show()