# 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
import matplotlib.pyplot as plt
import seaborn as sns
#import openpyxl # para levantar excel de otros paqueres (no office)
# Levanto los datos en 3 diferentes dataframes
#Articulos
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'])
#df_articles
#Vendedores
df_sellers = pd.read_excel('/work/data/sellers.xlsx', index_col=0)
#df_sellers
#Ordenes
df_orders = pd.read_csv('/work/data/orders.csv')
df_orders
#sql_query
#df_articles
#df_sellers
# Exploración del df de artículos
print('Muestra de datos')
print(df_articles.head())
print('\nForma del dataframe')
print(df_articles.shape)
print('\nBuscar valores nulos')
print(df_articles.isnull().sum())
print('\nFormato de los datos del dataframe')
print(df_articles.dtypes)
# Exploración del df de vendedores
print('Muestra de datos')
print(df_sellers.head())
print('\nForma del dataframe')
print(df_sellers.shape)
print('\nBuscar valores nulos')
print(df_sellers.isnull().sum())
print('\nFormato de los datos del dataframe')
print(df_sellers.dtypes)
# Exploración del df de órdenes
print('Muestra de datos')
print(df_orders.head())
print('\nForma del dataframe')
print(df_orders.shape)
print('\nBuscar valores nulos')
print(df_orders.isnull().sum())
print('\nFormato de los datos del dataframe')
print(df_orders.dtypes)
# Cambiar a float los precios unitarios
df_articles['unit_price'] = df_articles['unit_price'].astype(float)
print(df_articles.dtypes)
#Creo una copia del df_orders
my_df = df_orders.copy()
# Cambio el indice del df_articles común de 1, 2 3 por articles_id
df_articles.set_index('article_id', inplace=True)
# Agrego 3 columnas y pongo el campo que me va a servir de "ancla" para buscar la información real.
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'])
print(df_articles)
#print(my_df.head())
#Reemplazar los valores reales en el df
for i in range (len(my_df.index)): #len(my_df.index) devuelva la cantidad de filas (registros)
#reemplazo el nombre del articulo usando el id guardado en my_df
article = df_articles.loc[my_df.loc[i]['article_id']]['article_name']
my_df.loc[i, 'article_name'] = article
#reemplazo el nombre del vendedor usando el id guardado en my_df
my_df.loc[i, 'seller_name'] = df_sellers.loc[my_df.loc[i]['seller_id']]['seller_name']
#busco el precio unitario y lo multiplico por la cantidad de unidades vendidas.
my_df.loc[i, 'total_amount'] = df_articles.loc[my_df.loc[i]['article_id']]['unit_price'] * my_df.loc[i, 'quantity']
#elimino las columnas que no utilizo
my_df.drop(['article_id', 'seller_id', 'order_id'], axis='columns', inplace=True)
print(my_df.head())
# RESOLUCIÓN ANALÍTICA
#1. Sumo todos los artículos por el mismo nombre y tomo la cantidad
#2. Le digo que me los agrupe según (groupby) 'article_name'
#3. Le digo que me ordene los valores por 'quantity', y que el ascending sea False (mayor a menor)
#4. Imprimo solo el primer resultado con 'head(1)'
my_df2 = my_df.groupby('article_name').sum()
mas_cantidad = my_df2.sort_values('quantity', ascending=False)
print(mas_cantidad['quantity'].head(1))
# RESOLUCIÓN GRÁFICA
#Análisis de la resolución analítica: El artículo más vendido es 'HDD 413'
#Hice un gráfico de barras con la cantidad de los artículos más vendidos
sns.set_theme(style = 'whitegrid')
sns.barplot(x=my_df2.index, y=my_df2['quantity'], data = my_df2,
order=my_df2.sort_values('quantity', ascending=False).index,
palette='cool').set(title='Ventas por articulo')
plt.ylabel("Cantidad")
plt.xlabel(" ")
plt.xticks(rotation=90)
plt.show()
# RESOLUCIÓN ANALÍTICA
#1. Sumé todos los artículos por el mismo nombre y tomé 'total_amount'
#2. Los agrupé según (groupby) 'article_name'
#3. Ordené los valores por 'total_amount', con ascending en False (mayor a menor).
#4. Imprimí los primeros 5 resultados con 'head()'
my_df2 = my_df.groupby('article_name').sum()
mas_ingresos = my_df2.sort_values('total_amount', ascending=False).head()
print('Artículos con más ingresos', mas_ingresos['total_amount'])
# RESOLUCIÓN GRÁFICA
#Análisis de la resolución analítica: El artículo que más ingresos generó fue 'Full Pc'
#Hice gráfico de torta que muestra los porcentajes de venta de estos 5 artículos.
#Destaqué el más vendido separándolo para ver mejor qué porción representa.
colors = sns.color_palette('cool')
e = (0.1, 0, 0, 0, 0)
plt.pie(x=mas_ingresos['total_amount'], labels=mas_ingresos.index, colors=colors,
explode=e, startangle=270, autopct='%.0f%%', rotatelabels='true')
plt.title('Top 5 de los artículos que más ingresos generaron')
plt.show()
#OTRO ANÁLISIS
#Noté que el gráfico anterior no es completamente acertado ya que estaría faltando una categoría
#'Otros' que muestre el total de las ventas para que se pueda dimensionar mejor qué porcentaje
#represnta realmente el artículo más vendido.
#Para esto, ordené los artículos por ventas totales de forma inversa, y dejé afuera los últimos
#5 elementos, que corresponderías con los 5 más vendidos.
#A todo ese resto lo sumé.
my_df2 = my_df.groupby('article_name').sum()
mas_ingresos = my_df2.sort_values('total_amount', ascending=False).head()
otros = my_df2.sort_values('total_amount', ascending=True).head(-5)
total_otros = sum(otros['total_amount'])
print('Artículos con más ingresos', mas_ingresos['total_amount'])
print('Resto', total_otros)
#RESOLUCIÓN GRÁFICA
#Intenté agregar este resto como nuevo dato a la lista anterior para poder hacer el gráfico de
#torta, pero no pude por incompatibilidad de dimensiones, entre otros errores.
#Como tenía todos los datos, decidí forzarlo dándole yo misma los nombres y valores.
colors = sns.color_palette('cool')
e = (0.1, 0, 0, 0, 0, 0)
valores = [538335.93, 416124.42, 251000.00, 152250.00, 69477.48, 48620.00]
nombres = ['Full Pc', 'Otros', 'Notebook', 'Smartphone', 'Chair', 'Tablet']
plt.pie(valores, labels=nombres, colors=colors, explode=e, startangle=320, autopct='%.0f%%',
rotatelabels='true')
plt.title('Artículos que más ingresos generaron')
plt.show()
# RESOLUCIÓN ANALÍTICA
#Agrupé todos los vendedores por el mismo nombre y tomé el 'total_amount'
#Agrupé según (groupby) 'seller_name'
#Ordené los valores por 'total_amount', con ascending en False (= descendiente)
#Imprimo solo el primer resultado con 'head(1)'
my_df2 = my_df.groupby('seller_name').sum().sort_values('total_amount', ascending = False)
mejor_vendedor = my_df2.sort_values('total_amount', ascending=False)
print(mejor_vendedor['total_amount'].head(1))
# RESOLUCIÓN GRÁFICA
# Análisis de la resolución analítica: El mejor vendedor del mes fue Janel O'Curran
# Hice un gráfico de barras, y acomodé el nombre de los vendedores en otro ángulo.
sns.barplot(x=my_df2.index, y=my_df2['total_amount'], data = my_df2, order=my_df2.sort_values('total_amount', ascending=False).index, palette='cool').set(title='Empleado del Mes')
plt.ylabel("Monto")
plt.xticks(rotation=75)
plt.show()
# RESOLUCIÓN ANALÍTICA
#Agrupé por semana y tomé el 'total_amount'
#Agrupé según (groupby) 'week'
#Ordené los valores por 'total_amount', con ascending en False (= descendiente)
#Imprimí todos los resultados que eran 4 con head()'.
my_df2 = my_df.groupby('week').sum()
por_semanas = my_df2.sort_values('total_amount', ascending=False)
print(por_semanas['total_amount'].head())
# RESOLUCIÓN GRÁFICA
#Análisis de la resolución analítica: Las ventas han ido disminuyendo.
#Hice un gráfico de línea con sombra que me muestra el descenso en las ventas.
sns.lineplot(x=my_df2.index, y=my_df2['total_amount'], data = my_df2, marker = "o",
palette = 'cool').set(title='Ventas del Mes')
plt.xlabel("Semana")
plt.ylabel("Monto")
plt.fill_between(my_df2.index, my_df2['total_amount'], color = 'turquoise', alpha = 0.5)
plt.show()
# RESOLUCIÓN ANALÍTICA
#Agrupé todos los países por el mismo nombre y tomé su 'total_amount'.
#Los agrupé según (groupby) 'country_name'.
#Ordené los valores por 'total_amount', tomando el ascending como False (= descendiente)
#Imprimí solo el primer resultado con 'head(1)'
my_df2 = my_df.groupby('country_name').sum()
por_total = my_df2.sort_values('total_amount', ascending=False)
print(por_total['total_amount'].head(1))
#RESOLUCIÓN GRÁFICA
#Análisis de la resolución analítica: El país que más ingresos generó fue Brazil.
#Lo representé con un gráfico de barras por país y total de ventas.
#Para una mejor lectura, cambié el ángulo del nombre de los países.
#Eliminé el título del eje correspondiente a los países para evitar redundancias.
sns.barplot(y=my_df2.index, x=my_df2['total_amount'], data = my_df2,
order=my_df2.sort_values('total_amount', ascending=False).index,
palette='cool').set(title='País que más nos compró')
plt.xlabel("Monto")
plt.ylabel(" ")
plt.show()
# RESOLUCIÓN ANALÍTICA
#Agrupé todos los países por el mismo nombre y tomé la cantidad, 'quantity'.
#Los agrupé según (groupby) 'country_name'.
#Ordené los valores por 'quantity', con el ascending en False (= descendiente)
#Imprimí los primeros 3 resultados con 'head(3)'
my_df2 = my_df.groupby('country_name').sum()
por_cantidad = my_df2.sort_values('quantity', ascending=False)
print(por_cantidad['quantity'].head(3))
#RESOLUCIÓN GRÁFICA
#Análisis de la resolución: Además de ser el país que generó más ingresos, Brazil fue el
#que compró más cantidad de productos.
#Hice un gráfico de barras indicando la cantidad de artículos comprados.
#Limité la cantidad de países mostrados a 5.
sns.barplot(x=my_df2.index, y=my_df2['quantity'], data = my_df2,
order= my_df2[1:6].index,
palette='cool').set(title='País que más productos compró')
plt.ylabel("Cantidad de Productos")
plt.xlabel(" ")
plt.xticks(rotation=90)
plt.show()
# RESOLUCIÓN ANALÍTICA
#1. Sumé todos los artículos por el mismo nombre y tomé el 'total_amount'.
#2. Los agrupé según (groupby) 'article_name'.
#3. Ordeneé los valores por 'total_amount'.
#4. Imprimí solo los 10 primeros resultados con 'head(10)'.
my_df2 = my_df.groupby('article_name').sum()
por_total = my_df2.sort_values('total_amount', ascending=True)
print(por_total['total_amount'].head(10))
#RESOLUCIÓN GRÁFICA
#Análisis de la resolución: Ordenando los artículos de manera inversa puedo acceder a cuáles
#han sido menos vendidos y proceder a aplicar alguna estrategia de venta para generarles más salida.
sns.barplot(x=my_df2.index, y=my_df2['total_amount'], data = my_df2, order=my_df2.sort_values('total_amount', ascending=False).index, palette='cool').set(title='Productos que necesitan una mejor estrategia de venta')
plt.ylabel("Monto que se vendió")
plt.xticks(rotation=90)
plt.show()
#Las conclusiones y propuestas las fui agregando como comentario en cada uno de los casos
#para mayor claridad.