如何基于客户ID及月度订单数据计算客户churn(流失率)
月度客户流失率计算实现方案
规则说明
客户当月无下单记录则记为流失,有下单则记为未流失,暂不考虑规则带来的指标波动问题。
原始数据集结构
| date | CustomerID | Items |
|---|---|---|
| 2017-11-07 19:06:43 | 00001 | Bread, Milk |
| 2017-11-07 20:06:43 | 00002 | Dough |
| 2017-12-07 21:06:43 | 00003 | Apples |
| 2018-01-07 21:06:43 | 00002 | Carrots |
| 2018-01-07 21:06:43 | 00001 | Keyboard, Soymilk |
| 2018-02-07 21:06:43 | 00003 | Pie |
| 2018-03-07 21:06:43 | 00002 | Water |
| 2018-03-07 21:06:43 | 00003 | Chicken |
| 2018-04-07 21:06:43 | 00004 | Chewing Gum |
实现步骤
1. 数据预处理
首先将日期字段转为datetime格式,提取月份维度,方便后续按月聚合:
import pandas as pd from itertools import product # 转换日期格式 df['date'] = pd.to_datetime(df['date']) # 提取年月维度,格式如2017-11 df['month'] = df['date'].dt.to_period('M')
2. 生成客户-月份全量组合
现有重采样代码只能统计每月有订单的客户,要识别流失客户,需要先拿到所有客户在所有统计月份的全量对应关系,再匹配每个客户当月是否有下单:
# 提取所有不重复的客户ID all_customers = df['CustomerID'].unique() # 提取所有不重复的统计月份 all_months = df['month'].unique() # 生成客户和月份的笛卡尔积,确保每个客户每个月都有一条记录 customer_month_full = pd.DataFrame(product(all_customers, all_months), columns=['CustomerID', 'month'])
3. 匹配客户月度活跃/流失状态
# 对原始数据按客户+月份去重,有下单记录的标记为活跃 active_monthly = df.groupby(['CustomerID', 'month']).size().reset_index(name='is_active') active_monthly['is_active'] = 1 # 左关联全量组合,空值即为当月无下单的流失客户 customer_status = pd.merge(customer_month_full, active_monthly, on=['CustomerID', 'month'], how='left') # 空值填充为0,1代表未流失,0代表流失 customer_status['is_active'] = customer_status['is_active'].fillna(0).astype(int) # 新增流失标记字段:is_churn=1为流失,0为未流失 customer_status['is_churn'] = 1 - customer_status['is_active']
4. 按月计算流失率
monthly_churn = customer_status.groupby('month').agg( 总客户数=('CustomerID', 'count'), 流失客户数=('is_churn', 'sum') ).reset_index() monthly_churn['流失率'] = monthly_churn['流失客户数'] / monthly_churn['总客户数']
可选优化
如果不需要把「当月还未产生过任何订单的新客户」计入流失统计,可在生成全量组合时调整逻辑:仅为每个客户生成其首次下单之后所有月份的记录即可,更贴合实际业务的流失率定义。
内容的提问来源于stack exchange,提问作者PeterPost
相关产品推荐
相关产品推荐

