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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:34:08