Spaces:
Runtime error
Runtime error
| """ | |
| Analysis functions for sales data. | |
| """ | |
| import pandas as pd | |
| import numpy as np | |
| def get_top_models(sales_df, metric='Profit', n=10): | |
| """ | |
| Get top N models by profit or quantity. | |
| """ | |
| if sales_df.empty: | |
| return pd.DataFrame() | |
| if metric == 'Profit': | |
| result = sales_df.groupby('Model')['Profit'].sum().sort_values(ascending=False).head(n) | |
| elif metric == 'Quantity': | |
| result = sales_df.groupby('Model')['Quantity Sold'].sum().sort_values(ascending=False).head(n) | |
| else: | |
| result = sales_df.groupby('Model')[metric].sum().sort_values(ascending=False).head(n) | |
| return result.reset_index() | |
| def get_top_dealers(sales_df, metric='Profit', n=10): | |
| """ | |
| Get top N dealers by profit or quantity. | |
| """ | |
| if sales_df.empty: | |
| return pd.DataFrame() | |
| if metric == 'Profit': | |
| result = sales_df.groupby('Dealer ID')['Profit'].sum().sort_values(ascending=False).head(n) | |
| elif metric == 'Quantity': | |
| result = sales_df.groupby('Dealer ID')['Quantity Sold'].sum().sort_values(ascending=False).head(n) | |
| else: | |
| result = sales_df.groupby('Dealer ID')[metric].sum().sort_values(ascending=False).head(n) | |
| return result.reset_index() | |
| def get_monthly_trends(sales_df): | |
| """ | |
| Calculate monthly sales trends. | |
| """ | |
| if sales_df.empty: | |
| return pd.DataFrame() | |
| monthly = sales_df.groupby(['Year', 'Month_Num', 'Month_Name']).agg({ | |
| 'Profit': 'sum', | |
| 'Quantity Sold': 'sum' | |
| }).reset_index() | |
| monthly['Date'] = pd.to_datetime(monthly['Year'].astype(str) + '-' + monthly['Month_Num'].astype(str) + '-01') | |
| monthly = monthly.sort_values('Date') | |
| return monthly | |
| def get_yearly_summary(sales_df): | |
| """ | |
| Get yearly summary statistics. | |
| """ | |
| if sales_df.empty: | |
| return pd.DataFrame() | |
| yearly = sales_df.groupby('Year').agg({ | |
| 'Profit': 'sum', | |
| 'Quantity Sold': 'sum', | |
| 'Avg_Profit_Per_Unit': 'mean' | |
| }).reset_index() | |
| yearly['Profit_Growth'] = yearly['Profit'].pct_change() * 100 | |
| yearly['Units_Growth'] = yearly['Quantity Sold'].pct_change() * 100 | |
| return yearly | |
| def get_model_performance(sales_df): | |
| """ | |
| Analyze performance by model. | |
| """ | |
| if sales_df.empty: | |
| return pd.DataFrame() | |
| performance = sales_df.groupby('Model').agg({ | |
| 'Profit': 'sum', | |
| 'Quantity Sold': 'sum', | |
| 'Avg_Profit_Per_Unit': 'mean', | |
| 'Dealer ID': 'nunique' | |
| }).rename(columns={'Dealer ID': 'Num_Dealers'}).reset_index() | |
| performance['Profit_Per_Dealer'] = performance['Profit'] / performance['Num_Dealers'] | |
| performance['Units_Per_Dealer'] = performance['Quantity Sold'] / performance['Num_Dealers'] | |
| return performance.sort_values('Profit', ascending=False) | |
| def get_seasonal_analysis(sales_df): | |
| """ | |
| Analyze seasonal patterns by month. | |
| """ | |
| if sales_df.empty: | |
| return pd.DataFrame() | |
| seasonal = sales_df.groupby('Month_Name').agg({ | |
| 'Profit': 'mean', | |
| 'Quantity Sold': 'mean' | |
| }).reset_index() | |
| # Order months correctly | |
| month_order = ['January', 'February', 'March', 'April', 'May', 'June', | |
| 'July', 'August', 'September', 'October', 'November', 'December'] | |
| seasonal['Month_Order'] = seasonal['Month_Name'].apply(lambda x: month_order.index(x) if x in month_order else 0) | |
| seasonal = seasonal.sort_values('Month_Order') | |
| return seasonal | |
| def get_recalls_impact(recalls_df, sales_df): | |
| """ | |
| Analyze potential impact of recalls on sales. | |
| """ | |
| if recalls_df.empty or sales_df.empty: | |
| return pd.DataFrame() | |
| recall_by_model = recalls_df.groupby('Model').agg({ | |
| 'Units': 'sum', | |
| 'System_Affected': lambda x: list(x) | |
| }).reset_index() | |
| # Merge with sales performance | |
| model_performance = get_model_performance(sales_df) | |
| impact_analysis = model_performance.merge( | |
| recall_by_model, | |
| on='Model', | |
| how='left' | |
| ) | |
| impact_analysis['Recall_Units'] = impact_analysis['Units'].fillna(0) | |
| impact_analysis['Recall_Ratio'] = impact_analysis['Recall_Units'] / impact_analysis['Quantity Sold'] | |
| impact_analysis['Recall_Ratio'] = impact_analysis['Recall_Ratio'].fillna(0) | |
| return impact_analysis.sort_values('Recall_Ratio', ascending=False) | |
| def get_dealer_performance_with_details(sales_df, dealers_df): | |
| """ | |
| Get detailed dealer performance including location data. | |
| """ | |
| if sales_df.empty or dealers_df.empty: | |
| return pd.DataFrame() | |
| sales_by_dealer = sales_df.groupby('Dealer ID').agg({ | |
| 'Profit': 'sum', | |
| 'Quantity Sold': 'sum' | |
| }).reset_index() | |
| result = sales_by_dealer.merge( | |
| dealers_df[['Dealer ID', 'Dealer Name', 'City', 'State', 'Country', 'Latitude', 'Longitude']], | |
| on='Dealer ID', | |
| how='left' | |
| ) | |
| return result | |
| def get_model_ranking_over_time(sales_df, n_models=5): | |
| """ | |
| Track top models' performance over time. | |
| """ | |
| if sales_df.empty: | |
| return pd.DataFrame() | |
| # Get top N models overall | |
| top_models = sales_df.groupby('Model')['Profit'].sum().nlargest(n_models).index.tolist() | |
| # Filter and aggregate monthly | |
| filtered = sales_df[sales_df['Model'].isin(top_models)] | |
| monthly = filtered.groupby(['Year', 'Month_Num', 'Model'])['Profit'].sum().reset_index() | |
| monthly['Date'] = pd.to_datetime(monthly['Year'].astype(str) + '-' + monthly['Month_Num'].astype(str) + '-01') | |
| return monthly | |
| def get_quarterly_breakdown(sales_df): | |
| """ | |
| Get quarterly breakdown of sales. | |
| """ | |
| if sales_df.empty: | |
| return pd.DataFrame() | |
| quarterly = sales_df.groupby('Year_Quarter').agg({ | |
| 'Profit': 'sum', | |
| 'Quantity Sold': 'sum' | |
| }).reset_index() | |
| # Extract year and quarter for sorting | |
| quarterly[['Year', 'Quarter']] = quarterly['Year_Quarter'].str.split('-Q', expand=True) | |
| quarterly['Year'] = quarterly['Year'].astype(int) | |
| quarterly['Quarter'] = quarterly['Quarter'].astype(int) | |
| quarterly = quarterly.sort_values(['Year', 'Quarter']) | |
| return quarterly | |