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

如何基于成员生日计算对应分组12个月区间的月度计数均值

实现方案

以下先提供你需要的循环实现写法,再附上性能更优的简便实现方案,两种方案都可以直接替换列名后运行。

前置预处理

无论用哪种方案,先统一把两个数据集的年月转换为pandas月周期类型,避免跨年跨月的计算错误:

import pandas as pd
import numpy as np

# 替换为你实际使用的列名即可
DF1['ym'] = pd.PeriodIndex(year=DF1['年份列'], month=DF1['月份列'], freq='M')
DF2['birth_ym'] = pd.PeriodIndex(year=DF2['生日年'], month=DF2['生日月'], freq='M')

方法1:逐行循环实现

逻辑完全匹配需求描述,逐行处理DF2中的每位成员:

  • 提取当前成员的分组ID、生日起始月份
  • 生成从生日月开始的连续12个目标月份
  • 从DF1中筛选同分组、月份在目标范围内的月度计数
  • 计算均值存入结果列表,最后将列表作为新列追加到DF2
    代码如下:
# 为DF1构建分组+月份的联合索引,大幅提升循环中的筛选速度
DF1_indexed = DF1.set_index(['分组ID', 'ym']).sort_index()
mean_result = []

for _, row in DF2.iterrows():
    current_gid = row['分组ID']
    current_start_ym = row['birth_ym']
    # 生成连续12个月的周期列表
    target_months = [current_start_ym + offset for offset in range(12)]
    try:
        # 提取窗口内的计数值
        window_counts = DF1_indexed.loc[current_gid].loc[target_months, '月度计数字段'].to_numpy()
        mean_val = window_counts.mean()
    except KeyError:
        # 若存在分组不匹配、月份缺失的情况,返回空值,可按需修改默认填充值
        mean_val = np.nan
    mean_result.append(mean_val)

DF2['生日起始12个月计数均值'] = mean_result

该写法优势是逻辑直白、调试方便,适合万级以内的小数据集;缺点是逐行遍历性能差,百万级数据下运行速度较慢

方法2:高性能简便实现(无显式逐行循环)

先预构建每个分组的有序月度计数序列,避免循环过程中反复筛选DF1,性能比纯循环写法高10~100倍,代码维护性更好:

# 预构建每个分组的有序月份、计数数组,仅需遍历一次DF1
group_cache = {}
for gid, sub_df in DF1.groupby('分组ID'):
    sorted_sub = sub_df.sort_values('ym')
    group_cache[gid] = (
        sorted_sub['ym'].to_numpy(),
        sorted_sub['月度计数字段'].to_numpy()
    )

def calc_window_mean(gid, start_ym):
    if gid not in group_cache:
        return np.nan
    ym_array, count_array = group_cache[gid]
    # 定位生日月在序列中的起始索引
    start_pos = np.searchsorted(ym_array, start_ym)
    # 截取连续12个月的窗口计算均值
    window_data = count_array[start_pos : start_pos + 12]
    return window_data.mean() if len(window_data) > 0 else np.nan

# 批量计算所有成员的均值
DF2['生日起始12个月计数均值'] = DF2.apply(lambda x: calc_window_mean(x['分组ID'], x['birth_ym']), axis=1)

补充提示:如果DF1存在月度数据缺失,先执行下面的代码按分组补全所有月份,避免窗口长度不足12个月导致均值计算偏差:

DF1 = DF1.set_index('ym').groupby('分组ID')['月度计数字段'].resample('M').sum().reset_index()

如果DF1是完全连续无缺失的月度数据,还可以提前给每个分组预计算所有月份作为起始点的12个月滚动均值,直接通过表连接匹配结果,不需要使用apply,千万级数据也能秒级出结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 02:03:43