基于用户首次交易日期,用Pandas按6个月周期分组汇总客户利润
按用户首次交易日期的6个月周期汇总利润
原始数据集
| Customer ID | Date | Profit |
|---|---|---|
| 1 | 4/13/2018 | 10.00 |
| 1 | 4/26/2018 | 13.27 |
| 1 | 10/23/2018 | 15.00 |
| 2 | 1/1/2017 | 7.39 |
| 2 | 7/5/2017 | 9.99 |
| 2 | 7/7/2017 | 10.01 |
| 3 | 5/4/2019 | 30.30 |
需求说明
需要基于每个用户的首次交易日期作为起始点,按每6个月的周期分组汇总利润。理想输出如下:
| Customer ID | Date | Profit |
|---|---|---|
| 1 | 4/13/2018 | 23.27 |
| 1 | 10/13/2018 | 15.00 |
| 2 | 1/1/2017 | 7.39 |
| 2 | 7/1/2017 | 20.00 |
| 3 | 5/4/2019 | 30.30 |
现有代码问题
当前尝试的代码是基于自然时间的6个月周期(比如1月、7月为固定节点),无法以用户首次交易日期为起点进行分组:
df.groupby(['Customer ID',pd.Grouper(key='Date', freq='6M', closed='left')])['Profit'].sum().reset_index()
解决方案
要实现以用户首次交易日期为起点的6个月周期分组,需要先锚定每个用户的起始日期,再计算每条记录所属的周期区间,最后分组汇总。具体步骤如下:
- 先将
Date列转换为datetime类型:
df['Date'] = pd.to_datetime(df['Date'])
- 计算每个用户的首次交易日期并合并到原数据:
first_dates = df.groupby('Customer ID')['Date'].min().rename('First_Date') df = df.merge(first_dates, on='Customer ID')
- 计算每条记录距离首次交易的月份差,并划分周期:
# 计算累计月份差 df['months_since_first'] = (df['Date'].dt.year - df['First_Date'].dt.year)*12 + (df['Date'].dt.month - df['First_Date'].dt.month) # 按6个月为单位划分周期(0=首次交易后0-5个月,1=6-11个月,以此类推) df['period'] = df['months_since_first'] // 6
- 按用户和周期分组,汇总利润并生成周期起始日期:
result = df.groupby(['Customer ID', 'period']).agg( Date=('First_Date', lambda x: x.iloc[0] + pd.DateOffset(months=x.name[1]*6)), Profit=('Profit', 'sum') ).reset_index(drop=True)
执行后得到的结果与理想输出一致,如果需要转换日期格式,可以添加:
result['Date'] = result['Date'].dt.strftime('%m/%d/%Y')
内容的提问来源于stack exchange,提问作者Sabrina Margetic
相关产品推荐
相关产品推荐

