基于客户个性化日期范围的Pandas分组触达次数统计方案
解决方案:统计客户上次预约后的营销触达次数
针对你的需求(基于12万条客户表、60万条营销表,统计每个客户上次预约日期后的触达次数),以下是两种高效可行的实现方法,同时解答你关于pd.merge_asof的疑问:
前提准备
首先确保两张表的日期字段为datetime类型,否则无法正确比较:
import pandas as pd # 转换日期列 df_customers['lastBookedDate'] = pd.to_datetime(df_customers['lastBookedDate']) df_campaigns['campaignDate'] = pd.to_datetime(df_campaigns['campaignDate'])
方法一:普通合并+过滤+计数
这是最直观的方案,适合当前客户表每个cust_id唯一的场景:
- 按
cust_id合并两张表,关联每个营销触达对应的客户预约日期 - 过滤出触达日期晚于上次预约日期的记录
- 按
cust_id统计次数,同时补全无触达客户的0值
# 合并营销表与客户表 merged_df = pd.merge(df_campaigns, df_customers, on='cust_id', how='left') # 筛选符合时间条件的触达记录 filtered_df = merged_df[merged_df['campaignDate'] > merged_df['lastBookedDate']] # 统计每个客户的有效触达次数 count_result = filtered_df.groupby('cust_id').size().reset_index(name='post_booked_campaign_count') # 补全所有客户,无触达的客户次数设为0 final_result = pd.merge( df_customers[['cust_id']], count_result, on='cust_id', how='left' ).fillna(0).astype({'post_booked_campaign_count': int})
方法二:使用pd.merge_asof
完全可以用pd.merge_asof实现,该方法更适合存在多组时间序列匹配的场景,当前场景下也能高效运行:
- 对两张表按
cust_id和日期排序(merge_asof要求输入表按匹配键排序) - 通过
merge_asof关联每个触达记录与对应客户的预约日期 - 过滤并统计次数,逻辑同方法一
# 按cust_id和日期排序 df_customers_sorted = df_customers.sort_values(['cust_id', 'lastBookedDate']) df_campaigns_sorted = df_campaigns.sort_values(['cust_id', 'campaignDate']) # 关联触达记录与客户预约日期 merged_asof = pd.merge_asof( df_campaigns_sorted, df_customers_sorted, on='cust_id', left_on='campaignDate', right_on='lastBookedDate', direction='backward' ) # 筛选并统计次数 filtered_asof = merged_asof[merged_asof['campaignDate'] > merged_asof['lastBookedDate']] count_asof = filtered_asof.groupby('cust_id').size().reset_index(name='post_booked_campaign_count') # 补全无触达客户 final_result_asof = pd.merge( df_customers[['cust_id']], count_asof, on='cust_id', how='left' ).fillna(0).astype({'post_booked_campaign_count': int})
性能说明
两种方法都能轻松处理你的数据规模:
- 方法一的合并操作基于哈希表,60万条营销表的合并耗时极短
- 方法二的排序操作时间复杂度为O(n log n),60万条数据的排序在普通机器上也能快速完成
你可以根据自己的代码习惯选择任意一种方案。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

