You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python/Pandas构建基于客户首次购买日期的复购矩阵

问题描述

我有一份重复客户购买数据集,包含以下列:

  • Customer:客户ID
  • Trans_Date:交易日期
  • No_Trans:客户的第n次购买(所有客户均为复购者)

数据快照(截至2020年4月18日):

CustomerTrans_DateNo_Trans
C13/15/201
C13/15/202
C13/17/203
C23/15/201
C23/17/202
C33/16/201
C33/18/202
C43/17/201
C43/18/202

需要生成如下目标矩阵,按首次购买日期统计购买者数量,同时统计各日期的复购次数:

DateFirst purchasers on date3/15/203/16/203/17/203/18/20
3/15/2021020
3/16/2010001
3/17/2010001
3/18/2000000

计算逻辑:

  • 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 11:17:39