From 2aa7e80cfd03b09ba1b531afb2fa07496a497a22 Mon Sep 17 00:00:00 2001 From: Tiger Ren Date: Sat, 24 Aug 2024 15:45:42 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84ACV=E5=88=86=E6=9E=90?= =?UTF-8?q?=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=B0=86=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E7=BB=93=E6=9E=9C=E8=BE=93=E5=87=BA=E5=88=B0excel?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- analyze_acv.py | 52 +++++++++++++++++++++-------------- analyze_acv_dist.py | 37 ++++++++++++------------- output/acv_analysis.xlsx | Bin 0 -> 12126 bytes output/acv_distribution.xlsx | Bin 0 -> 8895 bytes 4 files changed, 50 insertions(+), 39 deletions(-) create mode 100644 output/acv_analysis.xlsx create mode 100644 output/acv_distribution.xlsx diff --git a/analyze_acv.py b/analyze_acv.py index d598594..75c21e6 100644 --- a/analyze_acv.py +++ b/analyze_acv.py @@ -1,5 +1,7 @@ import pandas as pd from typing import List +from openpyxl import Workbook + def strip_character(column_name, characters: List[str]): new_col_name = column_name @@ -26,28 +28,36 @@ def calc_acv_sum(df, acv_name, group_by_column): df_grouped_sum[acv_name] = df_grouped_sum[acv_name].apply(lambda x: '{:,}'.format(x)) return df_grouped_sum +def save_to_excel(dataframes, sheet_names, output_file): + with pd.ExcelWriter(output_file, engine='openpyxl') as writer: + for df, sheet_name in zip(dataframes, sheet_names): + df.to_excel(writer, sheet_name=sheet_name, index=False) # 读取赢单Excel文件 df_win = pd.read_excel('./data_src/pingcap_won.xlsx') acv_name = 'ACV' +# 创建一个列表来存储所有的数据帧和对应的sheet名称 +dataframes = [] +sheet_names = [] + # ACV by 客户分类 -print("------ACV by 行业------") df_win_grouped_by_industry_sum = calc_acv_sum(df_win, acv_name, '客户分类') -print(refine_content(df_win_grouped_by_industry_sum)) +dataframes.append(refine_content(df_win_grouped_by_industry_sum)) +sheet_names.append("ACV by 行业") # Group by customer industry and calculate the average ACV for each group -print("------平均ACV by 行业------") df_win_grouped_by_industry_mean = calc_acv_mean(df_win, acv_name, '客户分类') -print(refine_content(df_win_grouped_by_industry_mean)) +dataframes.append(refine_content(df_win_grouped_by_industry_mean)) +sheet_names.append("平均ACV by 行业") -print("------ACV by 子行业------") df_win_grouped_by_sub_industry_sum = calc_acv_sum(df_win, acv_name, '客户行业') -print(refine_content(df_win_grouped_by_sub_industry_sum)) +dataframes.append(refine_content(df_win_grouped_by_sub_industry_sum)) +sheet_names.append("ACV by 子行业") -print("------平均ACV by 子行业------") df_win_grouped_by_sub_industry_mean = calc_acv_mean(df_win, acv_name, '客户行业') -print(refine_content(df_win_grouped_by_sub_industry_mean)) +dataframes.append(refine_content(df_win_grouped_by_sub_industry_mean)) +sheet_names.append("平均ACV by 子行业") # 读取Excel文件 df = pd.read_excel('./data_src/pingcap_pipeline.xlsx') @@ -55,22 +65,24 @@ df = pd.read_excel('./data_src/pingcap_pipeline.xlsx') # 按照"客户分类"列分组,并计算ACV列的和 acv_name = '预估 ACV' -print("------预估ACV by 行业------") df_pipeline_grouped_by_industry_sum = calc_acv_sum(df, acv_name, '负责人所属行业') -print(refine_content(df_pipeline_grouped_by_industry_sum)) +dataframes.append(refine_content(df_pipeline_grouped_by_industry_sum)) +sheet_names.append("预估ACV by 行业") - -print("------平均预估ACV by 行业------") df_pipeline_grouped_by_industry_mean = calc_acv_mean(df, acv_name, '负责人所属行业') -print(refine_content(df_pipeline_grouped_by_industry_mean)) +dataframes.append(refine_content(df_pipeline_grouped_by_industry_mean)) +sheet_names.append("平均预估ACV by 行业") - -print("------预估ACV by 子行业------") df_pipeline_grouped_by_sub_industry_sum = calc_acv_sum(df, acv_name, '客户行业') -print(refine_content(df_pipeline_grouped_by_sub_industry_sum)) +dataframes.append(refine_content(df_pipeline_grouped_by_sub_industry_sum)) +sheet_names.append("预估ACV by 子行业") - - -print("------平均预估ACV by 子行业------") df_pipeline_grouped_by_sub_industry_mean = calc_acv_mean(df, acv_name, '客户行业') -print(refine_content(df_pipeline_grouped_by_sub_industry_mean)) \ No newline at end of file +dataframes.append(refine_content(df_pipeline_grouped_by_sub_industry_mean)) +sheet_names.append("平均预估ACV by 子行业") + +# 保存所有数据帧到一个Excel文件中 +output_file = './output/acv_analysis.xlsx' +save_to_excel(dataframes, sheet_names, output_file) + +print(f"Analysis results have been saved to {output_file}") \ No newline at end of file diff --git a/analyze_acv_dist.py b/analyze_acv_dist.py index b116625..1d37ce1 100644 --- a/analyze_acv_dist.py +++ b/analyze_acv_dist.py @@ -1,5 +1,6 @@ import pandas as pd from typing import List +from openpyxl import Workbook def strip_character(column_name, characters: List[str]): @@ -25,27 +26,25 @@ def get_acv_distribution(df, acv_name, industry_col_name): industry_acv_distribution.loc['Total'] = industry_acv_distribution.sum() return industry_acv_distribution -# Define the bins for ACV intervals +# 新增函数:将结果保存到Excel +def save_to_excel(dfs, sheet_names, output_file): + with pd.ExcelWriter(output_file, engine='openpyxl') as writer: + for df, sheet_name in zip(dfs, sheet_names): + df.to_excel(writer, sheet_name=sheet_name) + +# 读取数据 df = pd.read_excel('./data_src/pingcap_won.xlsx') - - -print('---------成单:ACV Distribution by industry--------') - -print(get_acv_distribution(df, 'ACV', '客户分类')) - - -print('---------成单:ACV Distribution by sub-industry--------') - -print(get_acv_distribution(df, 'ACV', '客户行业')) - - df_pipeline = pd.read_excel('./data_src/pingcap_pipeline.xlsx') -print('---------Pipeline:ACV Distribution by industry--------') +# 获取各种分布 +won_industry_dist = get_acv_distribution(df, 'ACV', '客户分类') +won_sub_industry_dist = get_acv_distribution(df, 'ACV', '客户行业') +pipeline_industry_dist = get_acv_distribution(df_pipeline, '预估 ACV', '负责人所属行业') +pipeline_sub_industry_dist = get_acv_distribution(df_pipeline, '预估 ACV', '客户行业') -print(get_acv_distribution(df_pipeline, '预估 ACV', '负责人所属行业')) +# 保存结果到Excel +dfs = [won_industry_dist, won_sub_industry_dist, pipeline_industry_dist, pipeline_sub_industry_dist] +sheet_names = ['成单-行业分布', '成单-子行业分布', 'Pipeline-行业分布', 'Pipeline-子行业分布'] +save_to_excel(dfs, sheet_names, './output/acv_distribution.xlsx') - -print('---------Pipeline:ACV Distribution by sub-industry--------') - -print(get_acv_distribution(df_pipeline, '预估 ACV', '客户行业')) \ No newline at end of file +print("ACV distribution analysis completed. Results saved in './output/acv_distribution.xlsx'") \ No newline at end of file diff --git a/output/acv_analysis.xlsx b/output/acv_analysis.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..9a7b70572d5706d2d62a4503b0f16099c91a13a0 GIT binary patch literal 12126 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 literal 0 HcmV?d00001 diff --git a/output/acv_distribution.xlsx b/output/acv_distribution.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..3b7f3d7f04d0040bfbe087b5714a0d08ed350f1e GIT binary patch literal 8895 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 literal 0 HcmV?d00001