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

在R中遍历多财年每日数据,生成分客户类型活跃客户统计

解决方案:多财年每日活跃客户统计

核心思路

不用手动遍历每个财年,而是通过生成完整日期序列 + 事件流统计法来高效计算,避免循环带来的冗余和内存问题。以下是具体实现步骤:


1. 数据预处理

先统一日期格式,处理缺失的释放日期(活跃中客户用目标结束日期填充):

import pandas as pd
import datetime as dt

# 假设原始数据集为df
df['entrance_date'] = pd.to_datetime(df['entrance_date'])
df['release_date'] = pd.to_datetime(df['release_date'])

# 定义统计截止日期:可选当前日期或最近财年结束日
end_date = dt.date.today()  # 示例:用当前日期
# end_date = pd.to_datetime('2024-03-31')  # 若财年为4月至次年3月,用最近财年结束日

# 填充活跃中客户的release_date
df['release_date'] = df['release_date'].fillna(end_date)

2. 生成跨财年的完整日期序列

根据数据中最早财年的起始日期,生成到截止日期的所有日期:

# 自定义财年起始日期计算函数(支持自然年/4月起始财年,可扩展)
def get_fy_start(fy_year, fy_type="calendar"):
    if fy_type == "calendar":
        return pd.to_datetime(f"{fy_year}-01-01")
    elif fy_type == "april":  # 财年:当年4月至次年3月
        return pd.to_datetime(f"{fy_year-1}-04-01")

# 获取最早财年的起始日期
min_fy = df['fy_year'].min()
start_date = get_fy_start(min_fy, fy_type="calendar")  # 根据实际财年类型调整

# 生成完整日期序列
date_df = pd.DataFrame({"date": pd.date_range(start=start_date, end=end_date, freq="D")})

3. 事件流法统计每日活跃数

通过记录客户的「准入(+1)」和「释放次日(-1)」事件,再累计计算每日活跃数,效率远高于遍历每个客户的活跃区间:

# 生成所有客户的流入/流出事件
events = []
for _, row in df.iterrows():
    # 准入日:该客户计入活跃
    events.append({"date": row['entrance_date'], "cus_gr": row['cus_gr'], "change": 1})
    # 释放次日:该客户不再计入活跃(释放当日仍算活跃)
    events.append({"date": row['release_date'] + pd.Timedelta(days=1), "cus_gr": row['cus_gr'], "change": -1})

events_df = pd.DataFrame(events)

# 按日期+客户类型聚合事件变化量
events_agg = events_df.groupby(['date', 'cus_gr'])['change'].sum().reset_index()

# 合并完整日期序列,填充无事件日期的变化量为0
merged = pd.merge(date_df, events_agg, on="date", how="left")
merged['change'] = merged['change'].fillna(0)

# 按客户类型计算累计活跃数(即每日活跃客户量)
daily_active = merged.groupby('cus_gr').apply(
    lambda x: x.set_index('date')['change'].cumsum()
).unstack(level=0).fillna(0).astype(int).reset_index()

# 重命名列名(可选)
daily_active.columns = ['date'] + [f"active_{gr}" for gr in daily_active.columns[1:]]

4. (可选)按财年拆分结果

如果需要按财年区分统计结果,可添加财年标识列:

def get_fy(date, fy_type="calendar"):
    if fy_type == "calendar":
        return date.year
    elif fy_type == "april":
        return date.year if date.month >=4 else date.year -1

daily_active['fy_year'] = daily_active['date'].apply(get_fy)

最终的daily_active就是按日期、客户类型统计的每日活跃客户数DataFrame,自动覆盖从最早财年到截止日期的所有日期,无需手动循环单个财年。

内容的提问来源于stack exchange,提问作者Morrigan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 16:12:42