百万级客户盈利DataFrame时间序列提取:分析新产品盈利影响
问题
我有一个包含数百万客户盈利信息的大型DataFrame,每个客户有多行月度盈利记录(覆盖过去数年),每个客户都有对应的新产品启用日期。现在需要调整数据格式,把每个客户新产品启用前后若干个月的盈利数据整理成宽表,方便分析产品对盈利能力的影响。
示例数据
import pandas as pd from datetime import date data = pd.DataFrame({ 'client' : ['john', 'john','john','john','john','john','john','john','john','john','rambo','rambo','rambo','rambo','rambo','rambo','rambo','rambo','rambo','rambo'], 'profit' : [100, 200,200,150,300,0,50,1513,51,5465,54645,54654,4875,7875,5132,202,512,10,242,2131], 'date' : [date(2022,1,1),date(2022,2,1),date(2022,3,1),date(2022,4,1),date(2022,5,1),date(2022,6,1),date(2022,7,1),date(2022,8,1),date(2022,9,1),date(2022,10,1),date(2023,1,1),date(2023,2,1),date(2023,3,1),date(2023,4,1),date(2023,5,1),date(2023,6,1),date(2023,7,1),date(2023,8,1),date(2023,9,1),date(2023,10,1)], 'new_product_start_date' : [date(2022,6,1),date(2022,6,1),date(2022,6,1),date(2022,6,1),date(2022,6,1),date(2022,6,1),date(2022,6,1),date(2022,6,1),date(2022,6,1),date(2022,6,1),date(2023,4,1),date(2023,4,1),date(2023,4,1),date(2023,4,1),date(2023,4,1),date(2023,4,1),date(2023,4,1),date(2023,4,1),date(2023,4,1),date(2023,4,1)]})
目标输出格式
| client | start_date | profit_2months_before | profit_1months_before | profit_1months_after | profit_2months_after |
|---|---|---|---|---|---|
| John | 2023/01 | 100 | 120 | 500 | 400 |
解决方案
步骤1:计算日期与启用日的月份差
将日期转换为年月周期格式,方便计算相对差值:
# 转换为月份周期,提取年月维度 data['date_month'] = data['date'].dt.to_period('M') data['start_month'] = data['new_product_start_date'].dt.to_period('M') # 计算当前月份与启用月份的差值(整数) data['month_diff'] = (data['date_month'] - data['start_month']).astype(int)
步骤2:筛选目标时间范围的记录
根据需求筛选启用前后的指定月份(示例为前2、前1、后1、后2个月):
# 定义需要保留的月份差值 target_diffs = [-2, -1, 1, 2] filtered_data = data[data['month_diff'].isin(target_diffs)]
步骤3:映射差值为目标列名
将月份差值转换为用户需要的列名:
diff_col_mapping = { -2: 'profit_2months_before', -1: 'profit_1months_before', 1: 'profit_1months_after', 2: 'profit_2months_after' } filtered_data['col_name'] = filtered_data['month_diff'].map(diff_col_mapping)
步骤4:透视转换为宽表
通过透视表将长格式数据转为目标宽格式:
# 生成透视表,按客户和启用日期分组 result = filtered_data.pivot_table( index=['client', 'new_product_start_date'], columns='col_name', values='profit', aggfunc='first' # 每个客户对应每个差值仅一条记录,直接取第一个值 ).reset_index() # 格式化日期并调整列顺序 result = result.rename(columns={'new_product_start_date': 'start_date'}) result['start_date'] = result['start_date'].dt.strftime('%Y/%m') result = result[['client', 'start_date', 'profit_2months_before', 'profit_1months_before', 'profit_1months_after', 'profit_2months_after']]
大数据量优化建议
针对数百万客户的超大规模数据:
- 提前过滤无关列,仅保留
client、profit、date、new_product_start_date四列,减少内存占用 - 使用
dask.dataframe替代pandas,支持并行计算和分块处理 - 按
client分组后分批处理,避免一次性加载全部数据
内容的提问来源于stack exchange,提问作者FábioRB
相关产品推荐
相关产品推荐

