import streamlit as st import pandas as pd import plotly.express as px import matplotlib.pyplot as plt import numpy as np # Page configuration st.set_page_config(page_title="Customer Insights App", page_icon=":bar_chart:") # Load CSV files df = pd.read_csv("df_clean.csv") nombres_proveedores = pd.read_csv("nombres_proveedores.csv", sep=';') euros_proveedor = pd.read_csv("euros_proveedor.csv", sep=',') nombres_proveedores['codigo'] = nombres_proveedores['codigo'].astype(str) euros_proveedor['CLIENTE'] = euros_proveedor['CLIENTE'].astype(str) # Convertir todas las columnas excepto 'CLIENTE' a float en euros_proveedor for col in euros_proveedor.columns: if col != 'CLIENTE': euros_proveedor[col] = pd.to_numeric(euros_proveedor[col], errors='coerce') # Verificar si hay valores NaN después de la conversión if euros_proveedor.isna().any().any(): st.warning("Algunos valores en euros_proveedor no pudieron ser convertidos a números. Por favor, revise los datos de entrada.") # Ignore the last two columns df = df.iloc[:, :-2] # Ensure customer code is a string df['CLIENTE'] = df['CLIENTE'].astype(str) # Function to get supplier name def get_supplier_name(code): name = nombres_proveedores[nombres_proveedores['codigo'] == code]['nombre'].values return name[0] if len(name) > 0 else code # Function to create radar chart with square root transformation def radar_chart(categories, values, amounts, title): N = len(categories) angles = [n / float(N) * 2 * np.pi for n in range(N)] angles += angles[:1] fig, ax = plt.subplots(figsize=(12, 12), subplot_kw=dict(projection='polar')) # Apply square root transformation sqrt_values = np.sqrt(values) sqrt_amounts = np.sqrt(amounts) max_sqrt_value = max(sqrt_values) normalized_values = [v / max_sqrt_value for v in sqrt_values] total_sqrt_amount = sum(sqrt_amounts) normalized_amounts = [a / total_sqrt_amount for a in sqrt_amounts] normalized_values += normalized_values[:1] ax.plot(angles, normalized_values, 'o-', linewidth=2, color='#FF69B4', label='% Units (sqrt)') ax.fill(angles, normalized_values, alpha=0.25, color='#FF69B4') normalized_amounts += normalized_amounts[:1] ax.plot(angles, normalized_amounts, 'o-', linewidth=2, color='#4B0082', label='% Spend (sqrt)') ax.fill(angles, normalized_amounts, alpha=0.25, color='#4B0082') ax.set_xticks(angles[:-1]) ax.set_xticklabels(categories, size=8, wrap=True) ax.set_ylim(0, max(max(normalized_values), max(normalized_amounts)) * 1.1) circles = np.linspace(0, 1, 5) for circle in circles: ax.plot(angles, [circle]*len(angles), '--', color='gray', alpha=0.3, linewidth=0.5) ax.set_yticklabels([]) ax.spines['polar'].set_visible(False) plt.title(title, size=16, y=1.1) plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1)) return fig # Main page design st.title("Welcome to Customer Insights App") st.markdown(""" This app helps businesses analyze customer behaviors and provide personalized recommendations based on purchase history. Use the tools below to dive deeper into your customer data. """) # Navigation menu page = st.selectbox("Select the tool you want to use", ["", "Customer Analysis", "Customer Recommendations"]) # Home Page if page == "": st.markdown("## Welcome to the Customer Insights App") st.write("Use the dropdown menu to navigate between the different sections.") # Customer Analysis Page elif page == "Customer Analysis": st.title("Customer Analysis") st.markdown("Use the tools below to explore your customer data.") partial_code = st.text_input("Enter part of Customer Code (or leave empty to see all)") if partial_code: filtered_customers = df[df['CLIENTE'].str.contains(partial_code)] else: filtered_customers = df customer_list = filtered_customers['CLIENTE'].unique() customer_code = st.selectbox("Select Customer Code", customer_list) if customer_code: customer_data = df[df["CLIENTE"] == customer_code] customer_euros = euros_proveedor[euros_proveedor["CLIENTE"] == customer_code] if not customer_data.empty and not customer_euros.empty: st.write(f"### Analysis for Customer {customer_code}") # Get percentage of units sold for each manufacturer all_manufacturers = customer_data.iloc[:, 1:].T # Exclude CLIENTE column all_manufacturers.index = all_manufacturers.index.astype(str) # Get total sales for each manufacturer sales_data = customer_euros.iloc[:, 1:].T # Exclude CLIENTE column sales_data.index = sales_data.index.astype(str) # Sort manufacturers by percentage of units and get top 10 top_units = all_manufacturers.sort_values(by=customer_data.index[0], ascending=False).head(10) # Sort manufacturers by total sales and get top 10 top_sales = sales_data.sort_values(by=customer_euros.index[0], ascending=False).head(10) # Combine top manufacturers from both lists combined_top = pd.concat([top_units, top_sales]).index.unique() values = [] # Will store percentages manufacturers = [] amounts = [] # Will store total sales for m in combined_top: if m in all_manufacturers.index and m in sales_data.index: values.append(float(all_manufacturers.loc[m, customer_data.index[0]])) manufacturers.append(get_supplier_name(m)) amounts.append(float(sales_data.loc[m, customer_euros.index[0]])) st.write(f"### Results for top {len(manufacturers)} manufacturers (balanced by units % and total sales):") for manufacturer, value, amount in zip(manufacturers, values, amounts): st.write(f"{manufacturer} = {value:.2f}% of units, €{amount:.2f} total sales") if manufacturers: # Only create the chart if we have data fig = radar_chart(manufacturers, values, amounts, f'Radar Chart for Top {len(manufacturers)} Manufacturers of Customer {customer_code}') st.pyplot(fig) else: st.warning("No data available to create the radar chart.") # Customer sales 2021-2024 (if data exists) if 'VENTA_2021' in df.columns and 'VENTA_2022' in df.columns and 'VENTA_2023' in df.columns and 'VENTA_2024' in df.columns: years = ['2021', '2022', '2023', '2024'] sales_columns = ['VENTA_2021', 'VENTA_2022', 'VENTA_2023', 'VENTA_2024'] customer_sales = customer_data[sales_columns].values[0] fig_sales = px.line(x=years, y=customer_sales, markers=True, title=f'Sales Over the Years for Customer {customer_code}') fig_sales.update_layout(xaxis_title="Year", yaxis_title="Sales") st.plotly_chart(fig_sales) else: st.warning("Sales data for 2021-2024 not available.") else: st.warning(f"No data found for customer {customer_code}. Please check the code.") # Customer Recommendations Page elif page == "Customer Recommendations": st.title("Customer Recommendations") st.markdown(""" Get tailored recommendations for your customers based on their purchasing history. """) partial_code = st.text_input("Enter part of Customer Code for Recommendations (or leave empty to see all)") if partial_code: filtered_customers = df[df['CLIENTE'].str.contains(partial_code)] else: filtered_customers = df customer_list = filtered_customers['CLIENTE'].unique() customer_code = st.selectbox("Select Customer Code for Recommendations", customer_list) if customer_code: customer_data = df[df["CLIENTE"] == customer_code] if not customer_data.empty: st.write(f"### Purchase History for Customer {customer_code}") st.write(customer_data) st.write(f"### Recommended Products for Customer {customer_code}") # Placeholder for recommendation logic st.write("Product A, Product B, Product C") else: st.warning(f"No data found for customer {customer_code}. Please check the code.")