Pandas按CampaignSource分组计算步骤流失用户的优化方法
流失用户统计实现方案
基础信息
数据集结构
现有结构化数据集包含3列:
Steps:转化步骤CampaignSource:活动来源set_UserId:对应用户ID集合,为set类型,可直接做集合差集运算
样例数据规则:CampaignSource分为Pot、Daddy两类,每类下包含One、Two、Three三个递进步骤的用户集合。
计算规则
- 仅在相同
CampaignSource分组内做对比,逐相邻步骤计算用户差集,禁止跨来源对比 - 流失用户定义:存在于当前步骤、但未出现在同来源下一个步骤的用户
- 排除每个来源下无后续步骤的最后一步无效记录
- 最终输出字段需包含
Steps、UserId、CampaignSource三列
原有实现问题
原有实现采用多层循环+异常捕获的逻辑,存在两个明显缺陷:
loss_dict = { 'Steps':[], 'UserId':[], 'CampaignSource':[] } for a in camp_df['CampaignSource'].unique(): temp_df = camp_df.loc[camp_df['CampaignSource'] == a].reset_index(drop=True) # The dataset is ordered, i just could make it work in ordered manner for b,c in enumerate(zip(temp_df['UserId'],temp_df['Steps'],temp_df[['CampaignSource']])): try: loss_dict['Steps'].append(c[1]) loss_dict['UserId'].append(temp_df['UserId'][b]-temp_df['UserId'][b+1]) loss_dict['CampaignSource'].append(c[2]) except KeyError: continue
- 依赖索引越界的异常捕获跳过最后一步,逻辑不可靠,无法稳定剔除每个分组下的最后一步无效记录
- 多层循环嵌套逻辑冗余,运行效率低,可维护性差
优化实现方案
采用pandas原生分组移位方法实现,无冗余循环,自动过滤无效记录,逻辑稳定:
import pandas as pd # 若原数据已按来源+步骤顺序排列,可跳过此排序步骤 # 若Steps有自定义递进顺序,可先将Steps转为pandas有序分类类型,保证排序逻辑正确 camp_df = camp_df.sort_values(by=['CampaignSource', 'Steps']).reset_index(drop=True) # 同来源分组内,关联当前步骤对应的下一个步骤用户集合,每个分组最后一步自动赋值为NaN camp_df['next_step_user'] = camp_df.groupby('CampaignSource')['set_UserId'].shift(-1) # 直接剔除无后续步骤的最后一步无效记录 camp_df = camp_df.dropna(subset=['next_step_user']).copy() # 集合差集计算,得到当前步骤的流失用户集合 camp_df['UserId'] = camp_df.apply(lambda x: x['set_UserId'] - x['next_step_user'], axis=1) # 结果1:每行对应一个转化步骤,UserId列为该步骤流失用户集合 loss_result_set = camp_df[['Steps', 'CampaignSource', 'UserId']].reset_index(drop=True) # 结果2:每行对应一个流失用户(和常规用户明细表结构对齐),不需要可省略 loss_result_detail = loss_result_set.explode('UserId').reset_index(drop=True)
方案说明:
- 用
groupby + shift(-1)原生逻辑关联下序步骤数据,天然区分有/无后续步骤的记录,不需要手动判断索引边界或依赖异常捕获- 差集计算直接通过行级运算完成,代码简洁,运行效率高于逐行循环
- 支持两种输出格式,可根据业务需求选择保留集合格式或拆分为单用户明细行
内容的提问来源于stack exchange,提问作者INGl0R1AM0R1
相关产品推荐
相关产品推荐

