# A veces necesitamos instalar nuevas librerías en nuestros proyectos
!pip install openpyxl==3.0.10
Requirement already satisfied: openpyxl==3.0.10 in /root/venv/lib/python3.9/site-packages (3.0.10)
Requirement already satisfied: et-xmlfile in /root/venv/lib/python3.9/site-packages (from openpyxl==3.0.10) (1.1.0)
WARNING: You are using pip version 22.0.4; however, version 22.1.2 is available.
You should consider upgrading via the '/root/venv/bin/python -m pip install --upgrade pip' command.
# imports
import numpy as np
import pandas as pd
import sqlite3 as sql3
import openpyxl # para que levante bien el excel
import matplotlib.pyplot as plt
import seaborn as sns
# Levanto 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')
# 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)
Muestra de datos
article_id article_name unit_price
0 20015 Smartphone 525.00
1 20016 Full Pc 2127.81
2 20017 Monitor 230.00
3 20018 Tablet 130.00
4 20019 Desk 130.10
Formato del dataframe
(31, 3)
Búsqueda de valores nulos por columna
article_id 0
article_name 0
unit_price 0
dtype: int64
Formato de los datos por columna
article_id int64
article_name object
unit_price object
dtype: object
# Exploración del df de vendedores
print('Muestra de datos')
print(df_sellers.head().align)
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)
Muestra de datos
<bound method DataFrame.align of seller_name
seller_id
1 Aveline Swanwick
2 Jase Doy
3 Oliviero Charkham
4 Cornie Wynrehame
5 Ewell Peres>
Formato del dataframe
(15, 1)
Búsqueda de valores nulos por columna
seller_name 0
dtype: int64
Formato de los datos por columna
seller_name object
dtype: object
# 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)
Muestra de datos
order_id week article_id quantity seller_id country_name
0 15024 1 20039 10 10 Peru
1 15025 1 20029 15 5 Peru
2 15026 1 20024 5 14 Bolivia
3 15027 1 20018 9 14 Brazil
4 15028 1 20035 6 15 Mexico
Formato del dataframe
(1000, 6)
Búsqueda de valores nulos por columna
order_id 0
week 0
article_id 0
quantity 0
seller_id 0
country_name 0
dtype: int64
Formato de los datos por columna
order_id int64
week int64
article_id int64
quantity int64
seller_id int64
country_name object
dtype: object
df_articles['unit_price'] = df_articles['unit_price'].astype(float)
print(df_articles.dtypes)
article_id int64
article_name object
unit_price float64
dtype: object
# Creo una copia del df_orders
my_df = df_orders.copy()
# Cambio el índice del df de artículos
df_articles.set_index('article_id',inplace = True)
# Agrego algunas columnas y pongo el campo que me va a servir de "ancla" para acordarme
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 valores en el nuevo df
# 1. busco el nombre del artículo y lo asigno a una variable
# como df_articles está indexado por article_id, lo uso para ubicarme en
# el registro que busco
# SINTAXIS: df_articles.loc[indice][columna]
# [indice] va a ser el dato que obtengo de my_df.loc[i]['article_id']
# -> o sea, tomo registro a registro el article_id y lo uso para extraer
# el nombre del artículo
for i in range(len(my_df.index)): # len(my_df.index) devuelve la cantidad de registros
idArticulo = my_df.loc[i]['article_id']
nombreArticulo = df_articles.loc[idArticulo]['article_name']
# se lo asigno a la columna correspondiente
my_df.loc[i,'article_name'] = nombreArticulo
# hago lo mismo en un solo paso para la columna de total_amount
precioArticulo = df_articles.loc[idArticulo]['unit_price']
cantArticulo = my_df.loc[i]['quantity']
my_df.loc[i,'total_amount'] = precioArticulo * cantArticulo
# columna de seller_name
idVendedor = my_df.loc[i]['seller_id']
nombreVendedor = df_sellers.loc[idVendedor]['seller_name']
my_df.loc[i,'seller_name'] = nombreVendedor
# elimino las columnas que no necesito
my_df.drop(['order_id', 'article_id', 'seller_id'], axis = 'columns', inplace=True)
print(my_df)
week quantity country_name article_name total_amount seller_name
0 1 10 Peru Water Cooling 675.0 Cirilo Grandham
1 1 15 Peru Mouse 454.5 Ewell Peres
2 1 5 Bolivia Netbook 725.0 Janel O'Curran
3 1 9 Brazil Tablet 1170.0 Janel O'Curran
4 1 6 Mexico Case 227.4 Daisie Slograve
.. ... ... ... ... ... ...
995 4 1 Brazil Modem 67.5 Kati Innot
996 4 15 Brazil Heatsink 150.0 Daisie Slograve
997 4 2 Colombia Heatsink 20.0 Vasily Danilyuk
998 4 14 Brazil Tablet 1820.0 Vasily Danilyuk
999 4 12 Brazil SDD 264.0 Onida Cosely
[1000 rows x 6 columns]
# SI SOBRA TIEMPO Se puede mencionar la función merge para hacer joins entre dataframes
# 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))
mes ventas costos
0 ene 10 7
1 feb 20 16
2 mar 30 25
3 abr 15 12
# RESOLUCIÓN ANALÍTICA
df_suma_de_ventas=my_df.groupby('article_name').sum().reset_index()
#Quiero Obtener los 5 primeros para graficar
primeros_cinco = df_suma_de_ventas.sort_values('quantity', ascending=False).head(5)
print(primeros_cinco['quantity'].head(1))
print(primeros_cinco)
#print(f'El articulo mas vendido fue {primeros_cinco["article_name"][0]}')
6 413
Name: quantity, dtype: int64
article_name week quantity total_amount
6 HDD 113 413 22558.06
25 Tablet 90 374 48620.00
21 SDD 86 372 8184.00
14 Mouse 71 322 9756.60
15 Netbook 95 320 46400.00
# RESOLUCIÓN GRÁFICA
print('Artículos mas vendidos')
sns.barplot(y=primeros_cinco["quantity"], x=primeros_cinco.index)
plt.xticks(rotation=75)
plt.title('Ventas por artículos')
plt.ylabel('Cantidades') #Agrego label eje Y
plt.xlabel('Artículos') #Agrego label eje X
plt.show()
Artículos mas vendidos
# RESOLUCIÓN ANALÍTICA
#Genero los dataframes que voy a utilizar
df_totales = my_df.groupby(by='article_name').sum()
df_top_diez = df_totales.sort_values('total_amount', ascending=False).head(10)
#creo el gráfico
print(df_top_diez)
week quantity total_amount
article_name
Full Pc 70 253 538335.93
Notebook 69 251 251000.00
Smartphone 74 290 152250.00
Chair 56 207 69477.48
Tablet 90 374 48620.00
Monitor 53 208 47840.00
Netbook 95 320 46400.00
Scanner 54 221 40885.00
Motherboard 79 291 40268.58
CPU 66 266 37138.92
# RESOLUCIÓN GRÁFICA
#Genero los dataframes que voy a utilizar
df_totales = my_df.groupby(by='article_name').sum()
df_top_diez = df_totales.sort_values('total_amount', ascending=False).head(10)
#creo el gráfico
sns.barplot(x=df_top_diez['total_amount'], y=df_top_diez.index)
plt.title('Diez Artículos más vendidos')
plt.ylabel('Artículos')
plt.xlabel('Monto Total')
plt.show()
# RESOLUCIÓN ANALÍTICA
#genero el df de vendedores agrupando sus ventas
df_vendedores = (my_df.groupby(by='seller_name').sum()).sort_values('total_amount',ascending=False)
print(df_vendedores[['quantity']+['total_amount']].head(1))
quantity total_amount
seller_name
Janel O'Curran 703 192832.47
# RESOLUCIÓN GRÁFICA
e = [0.5] #seteamos el extrude que va a ser del valor mayor
exp = [e.append(0) for x in range(len(df_vendedores)-1)]
sns.set(rc={'figure.figsize':(6,6)})
graf_vendedores = sns.color_palette('pastel', n_colors=len(df_vendedores))
#Estilo dark
plt.style.use("dark_background")
plt.suptitle(t='Ventas por vendedor', y=1.2, fontsize='xx-large')
_, _, autotexts = plt.pie(df_vendedores['total_amount'], explode=e,labels=df_vendedores.index, colors=exp,radius=1.7,
autopct='%1.1f%%')
for ins in autotexts:
ins.set_color('black')
plt.show()
# RESOLUCIÓN ANALÍTICA
df_ventas_semana = (my_df.groupby(by='week').sum()).sort_values('total_amount',ascending=False)
print(df_ventas_semana['total_amount'])
week
1 507458.81
2 415364.44
3 329140.03
4 223844.56
Name: total_amount, dtype: float64
# RESOLUCIÓN GRÁFICA
sns.barplot(y=df_ventas_semana["total_amount"], x=df_ventas_semana.index, palette="Blues_d")
sns.set(rc={'figure.figsize':(7,7)})
plt.xlabel("Semanas")
plt.ylabel("Monto vendido")
plt.title("Monto vendido por semana")
plt.show()
# RESOLUCIÓN
por_paises = (my_df.groupby(by='country_name').sum()).sort_values('total_amount',ascending=True)
print(por_paises['total_amount'].head(5))
#modificamos el tamaño del gráfico
sns.set(rc={'figure.figsize':(10,5)})
plt.bar(por_paises.index,por_paises['total_amount'], color="orange")
plt.xticks(rotation=75, ha="right")
plt.xlabel("Países")
plt.ylabel("Monto ventas")
plt.title("total de ventas")
plt.show()
print("El país en el que debemos mejorar nuestra campaña de marketing es", por_paises.index[0])
country_name
Puerto Rico 1265.43
Paraguay 8195.12
Ecuador 17475.30
Uruguay 17843.09
Bolivia 22682.80
Name: total_amount, dtype: float64
El país en el que debemos mejorar nuestra campaña de marketing es Puerto Rico
# RESOLUCIÓN
# RESOLUCIÓN ANALÍTICA
#Obtenemos los totales
df_articulo_pais = my_df.groupby(['country_name', 'article_name']).sum()
lista_paises = my_df.groupby('country_name').sum().index.values
#dentro de este df vamos a colocar los datos obtenidos
df_final = pd.DataFrame(columns=['Artículo', 'Ventas'], index=lista_paises)
# Populamos el df
for p in lista_paises:
df = df_articulo_pais.loc[p]
v = df.max()['total_amount']
a = df[(df['total_amount'] == v)].index[0]
df_final.loc[p] = {'Artículo': a, 'Ventas': v}
df_final = df_final.sort_values(['Ventas'], ascending=False)
df_final.reset_index(inplace=True, drop=False)
df_final.columns = ['País','Artículo', 'Ventas']
print(df_final)
País Artículo Ventas
0 Brazil Full Pc 134052.03
1 Argentina Full Pc 95751.45
2 Colombia Full Pc 72345.54
3 Peru Full Pc 51067.44
4 Venezuela Full Pc 44684.01
5 Mexico Notebook 44000.0
6 El Salvador Full Pc 40428.39
7 Guatemala Full Pc 27661.53
8 Costa Rica Full Pc 23405.91
9 Honduras Notebook 14000.0
10 Bolivia Full Pc 10639.05
11 Uruguay Full Pc 8511.24
12 Ecuador Smartphone 7875.0
13 Chile Smartphone 6300.0
14 Paraguay Monitor 4370.0
15 Puerto Rico CPU 1256.58
# RESOLUCIÓN
#generamos el df de venderores por país
df_orders_copy = my_df.copy()
df_pais_vendedor = df_orders_copy.groupby(['country_name', 'seller_name']).sum()
#Listado de paises
paises = my_df.groupby('country_name').sum().index.values
#df donde colocaremos la data integrada
df_integrada = pd.DataFrame(columns=['Vendedor', 'Ventas'], index=paises)
for p in paises:
df = df_pais_vendedor.loc[p]
v = df.max()['total_amount']
s = df[(df['total_amount'] == v)].index[0]
df_integrada.loc[p] = {'Vendedor': s, 'Ventas': v}
df_integrada['Paises'] = df_integrada.index
lista_acotada = df_integrada.sort_values(by='Ventas').head(5)
print(lista_acotada.Vendedor)
Puerto Rico Ewell Peres
Paraguay Aveline Swanwick
Ecuador Oliviero Charkham
Chile Onida Cosely
Uruguay Janel O'Curran
Name: Vendedor, dtype: object