Spaces:
Sleeping
Sleeping
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) | |
# 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 | |
def radar_chart(categories, values, amounts, title): | |
# Number of variables | |
N = len(categories) | |
# Calculate angles for each point | |
angles = [n / float(N) * 2 * np.pi for n in range(N)] | |
angles += angles[:1] | |
# Initialize the plot | |
fig, ax = plt.subplots(figsize=(12, 12), subplot_kw=dict(projection='polar')) | |
# Normalize values and amounts | |
max_value = max(values) | |
normalized_values = [v / max_value for v in values] | |
total_amount = sum(amounts) | |
normalized_amounts = [a / total_amount for a in amounts] | |
# Draw polygon for units and fill it | |
normalized_values += normalized_values[:1] | |
ax.plot(angles, normalized_values, 'o-', linewidth=2, color='#FF69B4', label='% Units') | |
ax.fill(angles, normalized_values, alpha=0.25, color='#FF69B4') | |
# Draw polygon for amounts and fill it | |
normalized_amounts += normalized_amounts[:1] | |
ax.plot(angles, normalized_amounts, 'o-', linewidth=2, color='#4B0082', label='% Spend') | |
ax.fill(angles, normalized_amounts, alpha=0.25, color='#4B0082') | |
# Set axes | |
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) | |
# Draw reference circles | |
circles = np.linspace(0, 1, 5) | |
for circle in circles: | |
ax.plot(angles, [circle]*len(angles), '--', color='gray', alpha=0.3, linewidth=0.5) | |
# Remove radial labels and chart borders | |
ax.set_yticklabels([]) | |
ax.spines['polar'].set_visible(False) | |
# Add title and legend | |
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. | |
""") | |
# Customer filter field | |
partial_code = st.text_input("Enter part of Customer Code (or leave empty to see all)") | |
# Filter customer options that match the partial code | |
if partial_code: | |
filtered_customers = df[df['CLIENTE'].str.contains(partial_code)] | |
else: | |
filtered_customers = df | |
# Create a list of filtered customers for the selectbox | |
customer_list = filtered_customers['CLIENTE'].unique() | |
# Customer selection with filtered autocomplete | |
customer_code = st.selectbox("Select Customer Code", customer_list) | |
if customer_code: | |
# Filter data for the selected customer | |
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}") | |
# Define purchase threshold | |
purchase_threshold = 0 | |
# Get all manufacturers the customer bought from (ignore the customer column) | |
all_manufacturers = customer_data.iloc[:, 1:].T[customer_data.iloc[:, 1:].T[customer_data.index[0]] > purchase_threshold] | |
# Sort manufacturers by value in descending order | |
all_manufacturers = all_manufacturers.sort_values(by=customer_data.index[0], ascending=False) | |
# Prepare values and manufacturers | |
values = all_manufacturers[customer_data.index[0]].values.tolist() | |
manufacturers = [get_supplier_name(m) for m in all_manufacturers.index.tolist()] | |
# Get amounts in euros | |
amounts = [] | |
for m in all_manufacturers.index.tolist(): | |
if m in customer_euros.columns: | |
amounts.append(customer_euros[m].values[0]) | |
else: | |
amounts.append(0) | |
# If there are fewer than 3 manufacturers, add a third one with value 0 | |
if len(manufacturers) < 3: | |
manufacturers.append("Other") | |
values.append(0) | |
amounts.append(0) | |
# Display the results for each manufacturer | |
st.write(f"### Results for {len(manufacturers)} manufacturers (sorted):") | |
for manufacturer, value, amount in zip(manufacturers, values, amounts): | |
st.write(f"{manufacturer} = {value:.4f} units, €{amount:.2f}") | |
# Create and display the radar chart | |
fig = radar_chart(manufacturers, values, amounts, f'Radar Chart for {len(manufacturers)} Manufacturers of Customer {customer_code}') | |
st.pyplot(fig) | |
# 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. | |
""") | |
# Customer filter field | |
partial_code = st.text_input("Enter part of Customer Code for Recommendations (or leave empty to see all)") | |
# Filter customer options that match the partial code | |
if partial_code: | |
filtered_customers = df[df['CLIENTE'].str.contains(partial_code)] | |
else: | |
filtered_customers = df | |
# Create a list of filtered customers for the selectbox | |
customer_list = filtered_customers['CLIENTE'].unique() | |
# Customer selection with filtered autocomplete | |
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: | |
# Show selected customer's purchase history | |
st.write(f"### Purchase History for Customer {customer_code}") | |
st.write(customer_data) | |
# Generate recommendations (placeholder) | |
st.write(f"### Recommended Products for Customer {customer_code}") | |
# You can replace this with the logic of the recommendation model | |
st.write("Product A, Product B, Product C") | |
else: | |
st.warning(f"No data found for customer {customer_code}. Please check the code.") |