Introducción al Proyecto: Análisis de Cesta de Mercado¶
Este notebook presenta un análisis de cesta de mercado (Market Basket Analysis) aplicado a los datos de ventas de "Sano y Fresco". El objetivo principal es descubrir patrones de compra y relaciones entre los productos que adquieren los clientes.¶
Mediante la aplicación de algoritmos de reglas de asociación, busco identificar qué productos tienden a comprarse juntos. Esta información es invaluable para diversas estrategias comerciales, como:¶
- Optimización de la disposición en tienda: Colocar productos que se compran juntos cerca uno del otro.
- Recomendaciones de productos: Sugerir productos complementarios a los clientes durante su compra.
- Promociones cruzadas: Crear ofertas que incluyan grupos de productos frecuentemente comprados juntos.
- Gestión de inventario: Prever la demanda de productos basándose en la compra de otros artÃculos relacionados.
El análisis se realizará a partir de los datos de transacciones almacenados en una base de datos SQLite. Se explorarán métricas clave como el soporte, la confianza y el lift para evaluar la fuerza e interés de las reglas de asociación encontradas.¶
A continuación, se detallan los pasos seguidos en este análisis.¶
In [2]:
# sqlite3 para interactuar con bases de datos SQLite
import sqlite3
from itertools import combinations
import pandas as pd
In [3]:
conexion = sqlite3.connect('sanoyfresco.db')
Carga de los Datos provinientes de la base de datos "sanoyfresco.db"¶
Cargar la tabla completa 'tickets' de la base de datos en un DataFrame de pandas¶
In [ ]:
df = pd.read_sql_query("SELECT * FROM tickets", conexion)
df
Out[Â ]:
| id_pedido | id_cliente | fecha | hora | id_departamento | id_seccion | id_producto | nombre_producto | precio_unitario | cantidad | precio_total | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 112108 | 2023-02-02 00:00:00 | 10 | 4 | 83 | 49683 | Pepino Kirby | 0.99 | 4 | 3.96 |
| 1 | 1 | 112108 | 2023-02-02 00:00:00 | 10 | 4 | 24 | 13176 | Bolsa de Bananas Orgánicas | 2.45 | 4 | 9.80 |
| 2 | 1 | 112108 | 2023-02-02 00:00:00 | 10 | 4 | 24 | 47209 | Aguacate Hass Orgánico | 1.79 | 2 | 3.58 |
| 3 | 2 | 202279 | 2023-02-03 00:00:00 | 9 | 4 | 83 | 28985 | Col Rizada Orgánica de Michigan | 2.55 | 2 | 5.10 |
| 4 | 2 | 202279 | 2023-02-03 00:00:00 | 9 | 4 | 83 | 17794 | Zanahorias | 0.95 | 5 | 4.75 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 4975713 | 3421080 | 52726 | 2023-01-09 00:00:00 | 11 | 16 | 84 | 27845 | Leche Entera Orgánica | 0.99 | 3 | 2.97 |
| 4975714 | 3421080 | 52726 | 2023-01-09 00:00:00 | 11 | 4 | 83 | 41950 | Racimo de Tomates Orgánicos | 2.25 | 7 | 15.75 |
| 4975715 | 3421080 | 52726 | 2023-01-09 00:00:00 | 11 | 4 | 16 | 31717 | Cilantro Orgánico | 0.69 | 5 | 3.45 |
| 4975716 | 3421082 | 175185 | 2023-08-22 00:00:00 | 18 | 4 | 24 | 16797 | Fresas | 2.05 | 4 | 8.20 |
| 4975717 | 3421083 | 25247 | 2023-06-27 00:00:00 | 6 | 4 | 24 | 24852 | Banana | 1.05 | 2 | 2.10 |
4975718 rows × 11 columns
Cerrar la conexión a la base de datos para liberar recursos¶
In [ ]:
conexion.close()
Mostrando información sobre el DataFrame, incluyendo tipos de datos y valores no nulos¶
In [ ]:
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 4975718 entries, 0 to 4975717 Data columns (total 11 columns): # Column Dtype --- ------ ----- 0 id_pedido int64 1 id_cliente int64 2 fecha object 3 hora int64 4 id_departamento int64 5 id_seccion int64 6 id_producto int64 7 nombre_producto object 8 precio_unitario float64 9 cantidad int64 10 precio_total float64 dtypes: float64(2), int64(7), object(2) memory usage: 417.6+ MB
Calidad de los datos¶
aca faltaria el proceso complementario de calidad de los datos, pero como no se trata de un documento laboral diario, se omite.
In [ ]:
df['fecha'] = pd.to_datetime(df['fecha'])
Creando la cesta del usuario para proceder con el analisis en cuestion, se toman las columnas de id_pedido y nombre_producto para que esto sea fiel a la realidad¶
El nuevo DataFrame 'df_cesta' contiene solo las columnas 'id_pedido' y 'nombre_producto'¶
Esto se hace para preparar los datos para el análisis de la cesta de mercado¶
In [ ]:
df_cesta = df[['id_pedido','nombre_producto']]
df_cesta
Out[Â ]:
| id_pedido | nombre_producto | |
|---|---|---|
| 0 | 1 | Pepino Kirby |
| 1 | 1 | Bolsa de Bananas Orgánicas |
| 2 | 1 | Aguacate Hass Orgánico |
| 3 | 2 | Col Rizada Orgánica de Michigan |
| 4 | 2 | Zanahorias |
| ... | ... | ... |
| 4975713 | 3421080 | Leche Entera Orgánica |
| 4975714 | 3421080 | Racimo de Tomates Orgánicos |
| 4975715 | 3421080 | Cilantro Orgánico |
| 4975716 | 3421082 | Fresas |
| 4975717 | 3421083 | Banana |
4975718 rows × 2 columns
In [ ]:
df_agrupado = df_cesta.groupby('id_pedido')['nombre_producto'].apply(lambda producto: ','.join(producto))
# Mostrar el resultado agrupado
df_agrupado
Out[Â ]:
| nombre_producto | |
|---|---|
| id_pedido | |
| 1 | Pepino Kirby,Bolsa de Bananas Orgánicas,Aguaca... |
| 2 | Col Rizada Orgánica de Michigan,Zanahorias |
| 3 | Espinacas Baby Orgánicas |
| 5 | Bolsa de Bananas Orgánicas,Frambuesas Orgánica... |
| 10 | Banana,Cilantro Orgánico,Aguacate Orgánico,Ceb... |
| ... | ... |
| 3421077 | Frambuesas Orgánicas,CalabacÃn Orgánico,Leche ... |
| 3421078 | Manzanas Gala Orgánicas,Banana |
| 3421080 | Leche Entera Orgánica,Racimo de Tomates Orgáni... |
| 3421082 | Fresas |
| 3421083 | Banana |
2060188 rows × 1 columns
In [ ]:
df_transacciones = df_agrupado.str.get_dummies(sep=',')
# Mostrar el DataFrame transformado
df_transacciones
Out[Â ]:
| Agua con Gas de Pomelo | Aguacate Hass Orgánico | Aguacate Orgánico | Ajo Orgánico | Apio Orgánico en Ramillete Pequeño | Arándanos Orgánicos | Banana | Bolsa de Bananas Orgánicas | CalabacÃn Orgánico | Cebolla Amarilla Orgánica | ... | Manzana Honeycrisp Orgánica | Manzanas Gala Orgánicas | Pepino Kirby | Pepino Orgánico | Racimo de Tomates Orgánicos | Rúcula Baby Orgánica | Tomates Cherry Orgánicos | Uvas Rojas sin Semillas | Zanahorias | Zanahorias Baby Orgánicas | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id_pedido | |||||||||||||||||||||
| 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ... | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 5 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 10 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 3421077 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3421078 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ... | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3421080 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 3421082 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3421083 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2060188 rows × 40 columns
In [ ]:
soporte = df_transacciones.mean() * 100
# Ordenar los productos por soporte de mayor a menor
soporte.sort_values(ascending=False)
Out[Â ]:
| 0 | |
|---|---|
| Banana | 23.809381 |
| Bolsa de Bananas Orgánicas | 19.129710 |
| Fresas Orgánicas | 13.349170 |
| Espinacas Baby Orgánicas | 12.198935 |
| Aguacate Hass Orgánico | 10.703004 |
| Aguacate Orgánico | 8.929331 |
| Limón Grande | 7.791279 |
| Fresas | 7.241960 |
| Limones | 7.107944 |
| Leche Entera Orgánica | 6.918301 |
| Frambuesas Orgánicas | 6.906797 |
| Cebolla Amarilla Orgánica | 5.706324 |
| Ajo Orgánico | 5.521778 |
| CalabacÃn Orgánico | 5.302429 |
| Arándanos Orgánicos | 5.086138 |
| Pepino Kirby | 4.840044 |
| Manzana Fuji Orgánica | 4.502841 |
| Limón Orgánico | 4.422266 |
| Tomates Cherry Orgánicos | 4.266795 |
| Manzana Honeycrisp Orgánica | 4.231216 |
| Uvas Rojas sin Semillas | 4.200733 |
| Pepino Orgánico | 4.114091 |
| Manzana Honeycrisp | 4.036476 |
| Zanahorias Baby Orgánicas | 3.898528 |
| Agua con Gas de Pomelo | 3.839504 |
| Crema Orgánica | 3.827855 |
| Manzana Fuji Extra Grande Orgánica | 3.780189 |
| Cebollas Amarillas | 3.728592 |
| Rúcula Baby Orgánica | 3.671849 |
| Manzanas Gala Orgánicas | 3.665442 |
| Zanahorias | 3.647386 |
| Coliflor Fresca | 3.597876 |
| Hummus Original | 3.593798 |
| Cilantro Orgánico | 3.538900 |
| Crema | 3.470606 |
| Espárragos | 3.446724 |
| Cebolla Roja Orgánica | 3.429687 |
| Apio Orgánico en Ramillete Pequeño | 3.427891 |
| Col Rizada Orgánica de Michigan | 3.396632 |
| Racimo de Tomates Orgánicos | 3.239267 |
In [ ]:
def confianza(antecedente, consecuente):
# Filtro para las transacciones donde se compraron ambos productos (antecedente y consecuente)
conjunto_ac = df_transacciones[(df_transacciones[antecedente] == 1) &
(df_transacciones[consecuente] == 1)]
# Calcular la confianza como el número de transacciones con ambos productos
return len(conjunto_ac) / df_transacciones[antecedente].sum()
In [ ]:
def lift(antecedente, consecuente):
# Calcular el soporte del antecedente
soporte_a = df_transacciones[antecedente].mean()
# Calcular el soporte del consecuente
soporte_c = df_transacciones[consecuente].mean()
# Contar el número de transacciones donde se compraron ambos productos
conteo_ac = len(df_transacciones[(df_transacciones[antecedente] == 1) &
(df_transacciones[consecuente] == 1)])
# Calcular el soporte conjunto (probabilidad de comprar ambos productos)
soporte_ac = conteo_ac / len(df_transacciones)
# Calcular el lift como el soporte conjunto dividido por el producto de los soportes individuales
return soporte_ac / (soporte_a * soporte_c)
In [ ]:
umbral_confianza = 0.05
asociaciones = []
# Iterar a través de todas las combinaciones de dos productos en el DataFrame de transacciones
for antecedente, consecuente in combinations(df_transacciones.columns, 2):
# Calcular el soporte del antecedente
soporte_a = df_transacciones[antecedente].mean()
# Calcular la confianza entre el antecedente y el consecuente
conf = confianza(antecedente, consecuente)
# Si la confianza es mayor que el umbral definido, considerar esta combinación como una posible regla de asociación
if conf > umbral_confianza:
# Calcular el lift para la combinación
lift_valor = lift(antecedente, consecuente)
# Agregar la información de la regla de asociación a la lista
asociaciones.append({
'antecedente': antecedente,
'consecuente': consecuente,
'soporte_a': round(soporte_a * 100,1), # Soporte del antecedente
'confianza': round(conf * 100,1), # Confianza en porcentaje
'lift': round(lift_valor,1) # Valor del lift
})
# Conversion de la lista de diccionarios de asociaciones en un DataFrame de pandas
df_asociaciones = pd.DataFrame(asociaciones)
# Ordenar el DataFrame de reglas de asociación por el valor de lift de mayor a menor
df_asociaciones.sort_values(by='lift', ascending=False, inplace=True)
# Mostrar el DataFrame con las reglas de asociación encontradas, ordenadas por lift
df_asociaciones
Out[Â ]:
| antecedente | consecuente | soporte_a | confianza | lift | |
|---|---|---|---|---|---|
| 185 | Cebolla Roja Orgánica | Cilantro Orgánico | 3.4 | 12.8 | 3.6 |
| 224 | Cilantro Orgánico | Limones | 3.5 | 25.4 | 3.6 |
| 61 | Ajo Orgánico | Cebolla Amarilla Orgánica | 5.5 | 20.1 | 3.5 |
| 106 | Apio Orgánico en Ramillete Pequeño | Zanahorias | 3.4 | 12.0 | 3.3 |
| 102 | Apio Orgánico en Ramillete Pequeño | Pepino Orgánico | 3.4 | 12.7 | 3.1 |
| ... | ... | ... | ... | ... | ... |
| 136 | Bolsa de Bananas Orgánicas | Limón Grande | 19.1 | 5.2 | 0.7 |
| 38 | Aguacate Orgánico | Bolsa de Bananas Orgánicas | 8.9 | 13.0 | 0.7 |
| 58 | Ajo Orgánico | Banana | 5.5 | 17.4 | 0.7 |
| 3 | Agua con Gas de Pomelo | Bolsa de Bananas Orgánicas | 3.8 | 13.2 | 0.7 |
| 15 | Aguacate Hass Orgánico | Banana | 10.7 | 14.6 | 0.6 |
399 rows × 5 columns
Se Genera una tabla de los productos únicos con su 'id_producto', 'id_seccion', 'id_departamento' para enriquecer la tabla de reglas¶
Para mas comodidad, se crea un nuevo DataFrame 'productos_unicos' que contiene información sobre cada producto único¶
Se seleccionan las columnas 'id_producto', 'id_seccion', 'id_departamento' y 'nombre_producto'¶
drop_duplicates() se usa para asegurarse de que cada producto aparezca solo una vez¶
In [ ]:
productos_unicos = df[['id_producto', 'id_seccion', 'id_departamento', 'nombre_producto']].drop_duplicates()
# DataFrame de productos únicos
productos_unicos
Out[Â ]:
| id_producto | id_seccion | id_departamento | nombre_producto | |
|---|---|---|---|---|
| 0 | 49683 | 83 | 4 | Pepino Kirby |
| 1 | 13176 | 24 | 4 | Bolsa de Bananas Orgánicas |
| 2 | 47209 | 24 | 4 | Aguacate Hass Orgánico |
| 3 | 28985 | 83 | 4 | Col Rizada Orgánica de Michigan |
| 4 | 17794 | 83 | 4 | Zanahorias |
| 5 | 21903 | 123 | 4 | Espinacas Baby Orgánicas |
| 7 | 27966 | 123 | 4 | Frambuesas Orgánicas |
| 9 | 24852 | 24 | 4 | Banana |
| 10 | 31717 | 16 | 4 | Cilantro Orgánico |
| 11 | 47766 | 24 | 4 | Aguacate Orgánico |
| 12 | 4605 | 83 | 4 | Cebollas Amarillas |
| 13 | 21137 | 24 | 4 | Fresas Orgánicas |
| 14 | 49235 | 53 | 16 | Crema Orgánica |
| 15 | 27845 | 84 | 16 | Leche Entera Orgánica |
| 16 | 45066 | 24 | 4 | Manzana Honeycrisp |
| 17 | 44632 | 115 | 7 | Agua con Gas de Pomelo |
| 19 | 46979 | 83 | 4 | Espárragos |
| 21 | 42265 | 123 | 4 | Zanahorias Baby Orgánicas |
| 26 | 8518 | 83 | 4 | Cebolla Roja Orgánica |
| 34 | 41950 | 83 | 4 | Racimo de Tomates Orgánicos |
| 35 | 47626 | 24 | 4 | Limón Grande |
| 38 | 22935 | 83 | 4 | Cebolla Amarilla Orgánica |
| 41 | 4920 | 123 | 4 | Uvas Rojas sin Semillas |
| 47 | 21616 | 123 | 4 | Rúcula Baby Orgánica |
| 49 | 28204 | 24 | 4 | Manzana Fuji Orgánica |
| 52 | 16797 | 24 | 4 | Fresas |
| 53 | 39275 | 123 | 4 | Arándanos Orgánicos |
| 57 | 37646 | 24 | 4 | Manzanas Gala Orgánicas |
| 59 | 40706 | 123 | 4 | Tomates Cherry Orgánicos |
| 60 | 5876 | 24 | 4 | Limón Orgánico |
| 67 | 30391 | 83 | 4 | Pepino Orgánico |
| 70 | 24964 | 83 | 4 | Ajo Orgánico |
| 75 | 19057 | 24 | 4 | Manzana Fuji Extra Grande Orgánica |
| 85 | 26209 | 24 | 4 | Limones |
| 99 | 8277 | 24 | 4 | Manzana Honeycrisp Orgánica |
| 138 | 27104 | 83 | 4 | Coliflor Fresca |
| 156 | 30489 | 67 | 20 | Hummus Original |
| 159 | 44359 | 83 | 4 | Apio Orgánico en Ramillete Pequeño |
| 172 | 45007 | 83 | 4 | CalabacÃn Orgánico |
| 289 | 27086 | 53 | 16 | Crema |
Opto por enriquecer el DataFrame de reglas de asociación 'df_asociaciones' con información del antecedente¶
Se realiza una fusión (merge) con el DataFrame 'productos_unicos' utilizando el nombre del producto como clave¶
Se utiliza un left merge para mantener todas las reglas de asociación y agregar la información del producto correspondiente al antecedente¶
In [ ]:
df_asociaciones_enriquecido = df_asociaciones.merge(productos_unicos, left_on='antecedente', right_on='nombre_producto', how='left').drop(columns=['nombre_producto'])
# Renombrar las columnas para reflejar que la información añadida corresponde al antecedente
df_asociaciones_enriquecido.columns = ['antecedente', 'consecuente', 'soporte_a', 'confianza', 'lift', 'id_producto_a', 'id_seccion_a', 'id_departamento_a']
# Mostrar el DataFrame de reglas de asociación enriquecido
df_asociaciones_enriquecido
Out[Â ]:
| antecedente | consecuente | soporte_a | confianza | lift | id_producto_a | id_seccion_a | id_departamento_a | |
|---|---|---|---|---|---|---|---|---|
| 0 | Cebolla Roja Orgánica | Cilantro Orgánico | 3.4 | 12.8 | 3.6 | 8518 | 83 | 4 |
| 1 | Cilantro Orgánico | Limones | 3.5 | 25.4 | 3.6 | 31717 | 16 | 4 |
| 2 | Ajo Orgánico | Cebolla Amarilla Orgánica | 5.5 | 20.1 | 3.5 | 24964 | 83 | 4 |
| 3 | Apio Orgánico en Ramillete Pequeño | Zanahorias | 3.4 | 12.0 | 3.3 | 44359 | 83 | 4 |
| 4 | Apio Orgánico en Ramillete Pequeño | Pepino Orgánico | 3.4 | 12.7 | 3.1 | 44359 | 83 | 4 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 394 | Bolsa de Bananas Orgánicas | Limón Grande | 19.1 | 5.2 | 0.7 | 13176 | 24 | 4 |
| 395 | Aguacate Orgánico | Bolsa de Bananas Orgánicas | 8.9 | 13.0 | 0.7 | 47766 | 24 | 4 |
| 396 | Ajo Orgánico | Banana | 5.5 | 17.4 | 0.7 | 24964 | 83 | 4 |
| 397 | Agua con Gas de Pomelo | Bolsa de Bananas Orgánicas | 3.8 | 13.2 | 0.7 | 44632 | 115 | 7 |
| 398 | Aguacate Hass Orgánico | Banana | 10.7 | 14.6 | 0.6 | 47209 | 24 | 4 |
399 rows × 8 columns
Carga de las reglas generadas en un archivo CSV, posteriormente se utiliza este mismo en secciones como marketing o desarrollo para ser explotado al maximo.¶
In [ ]:
df_asociaciones_enriquecido.to_csv('reglas.csv', index=False, sep=';', decimal=',')
Visualizaciones¶
Se crea un gráfico de barras de los N productos principales por soporte utilizando la variable soporte para visualizar los productos más frecuentes.¶
In [ ]:
import matplotlib.pyplot as plt
import seaborn as sns
# visualizacion de top 20 productos
plt.figure(figsize=(12, 8))
soporte.sort_values(ascending=False).head(20).plot(kind='bar', color=sns.color_palette('viridis', 20))
plt.title('Top 20 Productos')
plt.xlabel('Nombre')
plt.ylabel('Soporte')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()
Generé un diagrama de dispersión para explorar la relación entre la confianza y la elevación del DataFrame df_asociaciones.¶
Paso a crear visualizaciones para mostrar la distribución de antecedentes y consecuentes por departamento utilizando el DataFrame df_asociaciones_enriquecido.¶
Se genera un diagrama de dispersión para explorar la relación entre la confianza y la elevación¶
Este diagrama de dispersión visualiza la relación entre la confianza y la elevación de las reglas de asociación generadas.¶
La confianza indica la probabilidad de que el consecuente se compre dado el antecedente, mientras que la elevación muestra la mayor probabilidad de que el consecuente se compre cuando el antecedente también se compra, en comparación con su probabilidad base.¶
El tamaño y el color de los puntos representan el apoyo del antecedente. Las reglas con mayor elevación y confianza, especialmente aquellas con mayor apoyo, suelen ser más interesantes y prácticas.¶
In [ ]:
plt.figure(figsize=(10, 6))
sns.scatterplot(data=df_asociaciones, x='confianza', y='lift', size='soporte_a', hue='soporte_a', sizes=(50, 1000), alpha=0.6)
plt.title('Relación entre la confianza y la sustentación')
plt.xlabel('Confianza (%)')
plt.ylabel('Lift')
plt.grid(True)
plt.legend(title='Soporte (%)', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
Ahora genero gráficos de barras para explorar la distribución de productos únicos en diferentes departamentos y secciones¶
In [ ]:
# Distribucion por Departamentos
plt.figure(figsize=(12, 6))
productos_unicos['id_departamento'].value_counts().sort_index().plot(kind='bar', color=sns.color_palette('viridis', len(productos_unicos['id_departamento'].unique())))
plt.title('Distribución de Productos por Departamentos')
plt.xlabel('Identificador de Departamento')
plt.ylabel('Número de Productos Únicos')
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()
# Distribucion por Sector
plt.figure(figsize=(20, 8))
productos_unicos['id_seccion'].value_counts().sort_index().plot(kind='bar', color=sns.color_palette('viridis', len(productos_unicos['id_seccion'].unique())))
plt.title('Distribución de Productos por Sector')
plt.xlabel('Identificador de Sector')
plt.ylabel('Número de Productos Únicos')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()