使用Pandas高效统计各时间段内的客户数量
高效统计各月度活跃客户数的Pandas方案
嘿,我完全懂你用自定义for循环处理这种时间区间统计时的痛苦——数据量一大就卡得不行!下面给你两个基于Pandas原生功能的高效实现方案,比手动循环快几个数量级,完全适配你的需求:
先明确你的数据与目标
原始输入DataFrame
import pandas as pd # 你的原始数据 df = pd.DataFrame({ 'customer': [100, 101, 102, 103, 104], 'Start_date': ['2016-06-01', '2017-06-01', '2016-04-01', '2015-06-03', '2016-06-01'], 'End_date': ['2018-01-01', '2019-01-01', '2017-04-01', '2016-01-01', '2018-01-01'] })
目标输出格式
Period Customers 2017-01 3 2017-02 5 2017-03 8 2017-04 9
方案一:基于explode的直观实现(适合中小数据集)
这个方法逻辑清晰,容易理解,用Pandas内置的period_range和explode替代循环:
# 1. 先将日期列转换为datetime类型 df['Start_date'] = pd.to_datetime(df['Start_date']) df['End_date'] = pd.to_datetime(df['End_date']) # 2. 为每个客户生成其覆盖的所有月度Period序列 df['Periods'] = df.apply( lambda x: pd.period_range(start=x['Start_date'], end=x['End_date'], freq='M'), axis=1 ) # 3. 展开每个客户的Period序列,变成一行对应一个客户+一个月度的结构 expanded_df = df.explode('Periods') # 4. 统计每个月度的唯一客户数 result = expanded_df.groupby('Periods')['customer'].nunique().reset_index(name='Customers') # (可选)补全中间缺失的月度(如果有的话),缺失月份客户数填0 min_period = expanded_df['Periods'].min() max_period = expanded_df['Periods'].max() all_periods = pd.period_range(min_period, max_period, freq='M') result = result.set_index('Periods').reindex(all_periods, fill_value=0).reset_index() # 重命名列到目标格式 result.columns = ['Period', 'Customers']
方案二:基于Numpy广播的矢量化实现(适合超大数据集)
如果你的数据量达到百万级,上面的apply还是会有性能瓶颈,这个完全矢量化的方法直接用Numpy广播处理,效率拉满:
# 1. 转换日期为月度Period类型 df['Start_date'] = pd.to_datetime(df['Start_date']) df['End_date'] = pd.to_datetime(df['End_date']) start_periods = df['Start_date'].dt.to_period('M') end_periods = df['End_date'].dt.to_period('M') # 2. 生成需要覆盖的所有月度Period all_periods = pd.period_range(start_periods.min(), end_periods.max(), freq='M') # 3. 用广播生成活跃矩阵:每行是一个客户,每列是一个月度,值为True表示该客户当月活跃 active_matrix = (start_periods.values[:, None] <= all_periods.values) & (end_periods.values[:, None] >= all_periods.values) # 4. 统计每个月度的活跃客户数 result = pd.DataFrame({ 'Period': all_periods, 'Customers': active_matrix.sum(axis=0) })
为什么这两个方案比for循环高效?
- 它们都用了Pandas/Numpy的底层优化操作,这些操作是用C语言实现的,比Python级别的for循环快几十到几百倍
- 完全避免了手动遍历每个客户和每个月份的冗余操作,利用矢量化处理批量数据
内容的提问来源于stack exchange,提问作者Bart Bisschops
相关产品推荐
相关产品推荐

