如何用Python/Pandas构建基于客户首次购买日期的复购矩阵
问题描述
我有一份重复客户购买数据集,包含以下列:
Customer:客户IDTrans_Date:交易日期No_Trans:客户的第n次购买(所有客户均为复购者)
数据快照(截至2020年4月18日):
| Customer | Trans_Date | No_Trans |
|---|---|---|
| C1 | 3/15/20 | 1 |
| C1 | 3/15/20 | 2 |
| C1 | 3/17/20 | 3 |
| C2 | 3/15/20 | 1 |
| C2 | 3/17/20 | 2 |
| C3 | 3/16/20 | 1 |
| C3 | 3/18/20 | 2 |
| C4 | 3/17/20 | 1 |
| C4 | 3/18/20 | 2 |
需要生成如下目标矩阵,按首次购买日期统计购买者数量,同时统计各日期的复购次数:
| Date | First purchasers on date | 3/15/20 | 3/16/20 | 3/17/20 | 3/18/20 |
|---|---|---|---|---|---|
| 3/15/20 | 2 | 1 | 0 | 2 | 0 |
| 3/16/20 | 1 | 0 | 0 | 0 | 1 |
| 3/17/20 | 1 | 0 | 0 | 0 | 1 |
| 3/18/20 | 0 | 0 | 0 | 0 | 0 |
计算逻辑:
- 3/15/20首次购买的C1、C2中,C1当日复购1次,C1和C2在3/17/20各复购1次,对应列值1和2
- 3/16/20首次购买的C3在3/18/20复购1次,对应列值1
- 3/17/20首次购买的C4在3/18/20复购1次,对应列值1
- 3/18/20无首次购买客户
Pandas实现方案
咱们一步步来实现需求:
1. 导入库并加载数据
首先导入Pandas,加载数据并转换日期格式(确保日期能正确排序和分组):
import pandas as pd # 加载数据集 data = pd.DataFrame({ 'Customer': ['C1', 'C1', 'C1', 'C2', 'C2', 'C3', 'C3', 'C4', 'C4'], 'Trans_Date': ['3/15/20', '3/15/20', '3/17/20', '3/15/20', '3/17/20', '3/16/20', '3/18/20', '3/17/20', '3/18/20'], 'No_Trans': [1, 2, 3, 1, 2, 1, 2, 1, 2] }) # 转换日期格式为datetime,方便后续处理 data['Trans_Date'] = pd.to_datetime(data['Trans_Date'], format='%m/%d/%y')
2. 关联客户的首次购买日期
通过分组客户ID,取交易日期的最小值得到每个客户的首次购买日期,再合并回原数据集:
# 获取每个客户的首次购买日期 first_purchase = data.groupby('Customer')['Trans_Date'].min().reset_index() first_purchase.columns = ['Customer', 'First_Purchase_Date'] # 合并回原数据集,让每条交易记录关联客户的首次购买日期 data = pd.merge(data, first_purchase, on='Customer')
3. 统计各日期的首次购买人数
筛选出首次购买记录(No_Trans=1),按首次购买日期分组统计客户数量,同时补全所有交易日期的记录:
# 统计每个日期的首次购买人数(去重客户) first_purchasers_count = data[data['No_Trans'] == 1].groupby('First_Purchase_Date')['Customer'].nunique().reset_index() first_purchasers_count.columns = ['Date', 'First purchasers on date'] # 获取所有交易日期,确保目标矩阵包含所有日期 all_dates = data['Trans_Date'].sort_values().unique() # 把首次购买人数表的索引设置为所有日期,缺失的日期填充0 first_purchasers_count = first_purchasers_count.set_index('Date').reindex(all_dates, fill_value=0).reset_index()
4. 统计各日期的复购次数
筛选出复购记录(No_Trans>1),按首次购买日期和交易日期分组统计次数,补全缺失的日期列:
# 筛选复购记录(排除首次购买的No_Trans=1) repeat_purchases = data[data['No_Trans'] > 1] # 按首次购买日期和交易日期分组,统计复购次数 repeat_counts = repeat_purchases.groupby(['First_Purchase_Date', 'Trans_Date']).size().unstack(fill_value=0) # 调整列名为目标格式(比如3/15/20) repeat_counts.columns = repeat_counts.columns.strftime('%m/%d/%y') # 重置索引并改名为Date repeat_counts = repeat_counts.reset_index().rename(columns={'First_Purchase_Date': 'Date'}) # 确保包含所有交易日期,缺失的列填充0 for date in all_dates.strftime('%m/%d/%y'): if date not in repeat_counts.columns: repeat_counts[date] = 0 # 按日期顺序排序列 repeat_counts = repeat_counts[['Date'] + list(all_dates.strftime('%m/%d/%y'))]
5. 合并结果生成目标矩阵
把首次购买人数和复购次数合并,调整日期格式后得到最终结果:
# 合并首次购买人数和复购次数 result = pd.merge(first_purchasers_count, repeat_counts, on='Date', how='left') # 把Date列转成目标格式 result['Date'] = result['Date'].strftime('%m/%d/%y') # 展示结果 print(result)
运行后输出的结果与目标矩阵完全一致:
Date First purchasers on date 3/15/20 3/16/20 3/17/20 3/18/20 0 3/15/20 2 1 0 2 0 1 3/16/20 1 0 0 0 1 2 3/17/20 1 0 0 0 1 3 3/18/20 0 0 0 0 0
内容的提问来源于stack exchange,提问作者rgo
相关产品推荐
相关产品推荐

