# A veces necesitamos instalar nuevas librerías en nuestros proyectos
# En este caso, instalamos openpyxl para trabajar con el DF sellers.xlsx
!pip install openpyxl==3.0.10
# imports
# Importamos los módulos estadísticos y graficadores, más los requeridos para trabajar los DF
import numpy as np
import pandas as pd
import sqlite3 as sql3
import openpyxl
import matplotlib.pyplot as plt
import seaborn as sns
# Levantamos los datos en 3 diferentes dataframes:
# Artículos:
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:
df_sellers = pd.read_excel('/work/data/sellers.xlsx', index_col=0)
# Órdenes:
df_orders = pd.read_csv('/work/data/orders.csv')
df_orders
# Exploración del df de 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)
print('\nLos IDs de producto no son unicos?')
print(df_articles['article_id'].is_unique)
# Exploración del df de 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 del df de ó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)
print('\nLos IDs de ordenes no son unicos?')
print(df_orders['order_id'].is_unique)
df_articles['unit_price'] = df_articles['unit_price'].astype(float)
print(df_articles.dtypes)
# Creamos una copia del df_orders:
my_df = df_orders.copy()
# Cambiamos el índice del df de artículos:
df_articles.set_index('article_id',inplace = True)
# Agregamos columnas nuevas:
my_df = my_df.assign(article_name = '')
my_df = my_df.assign(total_amount = 1)
my_df = my_df.assign(seller_name = '')
for i in range(len(my_df.index)):
# Recuperamos el nombre del articulo:
current_article_id = my_df.loc[i]['article_id']
current_article_name = df_articles.loc[current_article_id]['article_name']
my_df.loc[i,'article_name'] = current_article_name
# Calculamos el monto total:
current_article_unit_price = df_articles.loc[current_article_id]['unit_price']
current_quantity = my_df.loc[i, 'quantity']
my_df.loc[i,'total_amount'] = current_article_unit_price * current_quantity
# Recuperemos el nombre del vendedor:
current_seller_id = my_df.loc[i]['seller_id']
current_seller_name = df_sellers.loc[current_seller_id]['seller_name']
my_df.loc[i,'seller_name'] = current_seller_name
my_df.drop(['order_id', 'article_id', 'seller_id'], axis = 'columns', inplace=True)
print(my_df)
# https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.merge.html
d1=pd.DataFrame({'mes': ['ene','feb','mar','abr'], 'ventas':[10,20,30,15]})
d2=pd.DataFrame({'mes': ['ene','feb','mar','abr'], 'costos':[7,16,25,12]})
print(pd.merge(d1,d2))
# RESOLUCIÓN ANALÍTICA
sumatory_article_df = my_df.groupby('article_name').sum()
top_ten_articles_by_unit = sumatory_article_df.sort_values('quantity', ascending=False).head(10)
print(top_ten_articles_by_unit['quantity'].head(5))
# RESOLUCIÓN GRÁFICA
sns.barplot(y=top_ten_articles_by_unit["quantity"], x=top_ten_articles_by_unit.index)
plt.title('TOP TEN Articles by Units')
plt.xticks(rotation=60)
plt.xlabel('Articles')
plt.ylabel('Quantity')
plt.show()
# RESOLUCIÓN ANALÍTICA
sumatory_article_df = my_df.groupby(by='article_name').sum()
top_ten_articles_by_amount = sumatory_article_df.sort_values('total_amount', ascending=False).head(15)
print(top_ten_articles_by_amount['total_amount'].head(15))
# RESOLUCIÓN GRÁFICA
# Tomo sólo los 15 artículos que más ingresos proporcionaron
sns.barplot(x=top_ten_articles_by_amount['total_amount'], y=top_ten_articles_by_amount.index)
plt.title('TOP TEN Articles by Total Amount')
plt.ylabel('Articles')
plt.xlabel('Total Amount')
plt.show()
# RESOLUCIÓN ANALÍTICA
sumatory_sellers_df = my_df.groupby('seller_name').sum()
ranking_sellers_by_amount = sumatory_sellers_df.sort_values('total_amount', ascending=False)
print(ranking_sellers_by_amount['total_amount'].head(15))
# RESOLUCIÓN GRÁFICA
sns.barplot(y=ranking_sellers_by_amount['total_amount'], x=ranking_sellers_by_amount.index)
plt.xticks(rotation=90)
plt.xlabel('Seller')
plt.ylabel('Total amount')
plt.show()
# RESOLUCIÓN ANALÍTICA
sumatory_weeks_df = my_df.groupby('week').sum()
ranking_weeks_by_amount = sumatory_weeks_df.sort_values('total_amount', ascending=False)
weak_week = ranking_weeks_by_amount['total_amount'].tail(1)
print(ranking_weeks_by_amount)
# Semana mas debil (para lanzar campaña)
print(weak_week)
# RESOLUCIÓN GRÁFICA
ax = sns.barplot(y=ranking_weeks_by_amount['total_amount'], x=ranking_weeks_by_amount.index)
for i in ax.containers:
ax.bar_label(i,)
plt.xlabel('Week')
plt.ylabel('Total Amount')
plt.show()
# RESOLUCIÓN ANALÍTICA
# Los 5 paises en cuestion, debe ser extraido del DF my_df:
sumatory_countries_df = my_df.groupby('country_name').sum()
top_five_countries_by_amount = sumatory_countries_df.sort_values('total_amount', ascending=False).head(5)
print(top_five_countries_by_amount)
# RESOLUCIÓN GRÁFICA
colors = sns.color_palette('ch:s=.25,rot=-.25')[0:5]
plt.pie(top_five_countries_by_amount['total_amount'], labels = top_five_countries_by_amount.index, colors = colors, autopct='%.0f%%')
centre_circle = plt.Circle((0,0), 0.5, fc="white")
fig=plt.gcf()
fig.gca().add_artist(centre_circle)
# fin círculo
plt.savefig('plot.png', dpi=300)
plt.show()
# RESOLUCIÓN ANALÍTICA
df7 = my_df.query('week==4').groupby(by='seller_name').sum().sort_values(by='quantity', ascending=False).head(3)
print(df7['quantity'])
# RESOLUCIÓN GRÁFICA
cantidades_vendidas = df7['quantity'].values
for i, cant in enumerate(cantidades_vendidas):
plt.annotate(cant, (df7.index[i],cant))
plt.bar(df7.index,df7['quantity'])
plt.title('Vendedores que más artículos vendieron en la última semana', fontsize='large')
plt.xlabel('Vendedor')
plt.ylabel(ylabel='Cantidad')
plt.show()
# RESOLUCIÓN
# Extraigo los articulos que me interesan de la muestra.
boolean_mask_df = my_df['article_name'].isin(['Full Pc','Smartphone'])
selected_articles_df = my_df[boolean_mask_df].sort_values('country_name', ascending=True)
# Agrupo por Pais y Articulo para sumarizar.
selected_articles_sumatory_df = selected_articles_df.groupby(['country_name', 'article_name']).sum()
# Paso los indices a columnas para ayudar a plotearlos.
selected_articles_sumatory_df.reset_index(level=1, inplace=True)
plt.xticks(rotation=90)
sns.barplot(y=selected_articles_sumatory_df.index, x=selected_articles_sumatory_df['quantity'], hue=selected_articles_sumatory_df['article_name'])
plt.xlabel('Quantity')
plt.ylabel('Country')
plt.show()
# Trabajamos sobre los paises en los que las unidad de smartphones sobrepasan las pc:
resume_df = pd.DataFrame()
resume_df = resume_df.assign(smartphone_units = 0)
resume_df = resume_df.assign(full_pc_units = 0)
for index, row in selected_articles_sumatory_df.iterrows():
if (row['article_name'] == 'Smartphone'):
resume_df.loc[index,'smartphone_units'] = row['quantity']
if (row['article_name'] == 'Full Pc'):
resume_df.loc[index,'full_pc_units'] = row['quantity']
# Rellenamos con ceros los NaN:
resume_df = resume_df.fillna(0)
resume_df = resume_df[resume_df['smartphone_units'] > resume_df['full_pc_units']]
print(f'Los paises en los que las unidad de smartphones sobrepasan las pc completas son:')
for country in (resume_df.index):
print(f'- {country}')