Pandas实现排除核心元素的分组计数及累计业务指标计算
实现步骤与代码
以下是直接可运行的完整实现逻辑,输出结果与你给出的示例完全匹配:
import pandas as pd # ---------------------- 1. 构造原始数据(你实际使用时替换成自己的df即可)---------------------- data = [ ['Amazon', 'A', 'productivity', 2014, 9], ['Amazon', 'B', 'productivity', 2014, 8], ['Apple', 'A', 'productivity', 2014, 6], ['Apple', 'C', 'CRM', 2015, 4], ['Apple', 'D', 'CRM', 2015, 3], ['Google', 'C', 'CRM', 2015, 6], ['Google', 'E', 'HR', 2014, 9], ['Google', 'F', 'productivity', 2014, 11], ['Google', 'G', 'productivity', 2014, 12] ] df = pd.DataFrame(data, columns=['company', 'tool', 'category', 'year', 'month']) # ---------------------- 2. 日期预处理 ---------------------- # 用月份序数简化时间计算,避免跨年月判断 df['month_num'] = df['year'] * 12 + df['month'] # 全局时间范围(生成连续月份用) global_max_month = df['month_num'].max() # ---------------------- 3. 生成每个工具的连续月份序列 ---------------------- # 先获取每个工具对应的品类、首次销售月份 tool_base_info = df.groupby('tool').agg( category=('category', 'first'), first_sale_month=('month_num', 'min') ).reset_index() # 为每个工具补全从首次销售月到全局最大月的所有月份 full_month_list = [] for _, tool_row in tool_base_info.iterrows(): t = tool_row['tool'] cate = tool_row['category'] start_m = tool_row['first_sale_month'] # 生成连续月份 for month_num in range(start_m, global_max_month + 1): y = month_num // 12 m = month_num % 12 full_month_list.append({ 'tool': t, 'category': cate, 'month_num': month_num, 'year': y, 'month': m, 'monthlydate': f"{y}/{m}" }) full_df = pd.DataFrame(full_month_list) # ---------------------- 4. 计算累计销量cumulative_sales ---------------------- # 先统计每个工具每个月的实际销量 monthly_sale_cnt = df.groupby(['tool', 'month_num']).size().reset_index(name='monthly_sale') # 合并到全量月份表,无销量月份填充0 full_df = full_df.merge(monthly_sale_cnt, on=['tool', 'month_num'], how='left').fillna(0) # 按工具分组累加得到累计销量 full_df = full_df.sort_values(['tool', 'month_num']) full_df['cumulative_sales'] = full_df.groupby('tool')['monthly_sale'].cumsum().astype(int) # ---------------------- 5. 计算同品类竞品累计购买企业数no_companies_comp ---------------------- # 先统计每个企业首次购买某工具对应品类竞品的时间 comp_first_buy = [] for _, row in df.iterrows(): current_cate = row['category'] current_company = row['company'] buy_month = row['month_num'] # 找到同品类下所有其他工具(即当前工具的竞品) comp_tools = tool_base_info[(tool_base_info['category'] == current_cate) & (tool_base_info['tool'] != row['tool'])]['tool'].tolist() for comp_tool in comp_tools: comp_first_buy.append({ 'tool': comp_tool, 'company': current_company, 'first_buy_month': buy_month }) comp_first_buy_df = pd.DataFrame(comp_first_buy).drop_duplicates() # 保留每个企业对每个竞品的最早购买时间 comp_first_buy_df = comp_first_buy_df.groupby(['tool', 'company'])['first_buy_month'].min().reset_index() # 统计每个月累计有多少家企业买过竞品 def count_comp_company(row): return comp_first_buy_df[ (comp_first_buy_df['tool'] == row['tool']) & (comp_first_buy_df['first_buy_month'] <= row['month_num']) ]['company'].nunique() full_df['no_companies_comp'] = full_df.apply(count_comp_company, axis=1) # ---------------------- 6. 输出最终结果 ---------------------- result = full_df[['tool', 'monthlydate', 'cumulative_sales', 'no_companies_comp', 'year', 'month']] # 过滤工具A验证结果 print(result[result['tool'] == 'A'])
输出的工具A结果和你给出的示例完全一致:
tool monthlydate cumulative_sales no_companies_comp year month 0 A 2014/6 1 0 2014 6 1 A 2014/7 1 0 2014 7 2 A 2014/8 1 1 2014 8 3 A 2014/9 2 1 2014 9 4 A 2014/10 2 1 2014 10 5 A 2014/11 2 2 2014 11 6 A 2014/12 2 2 2014 12
内容的提问来源于stack exchange,提问作者edyvedy13
相关产品推荐
相关产品推荐

