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

如何用Pandas计算指定月份过去3个月的唯一员工ID数量?

解决方案:计算当月及过去3个月的唯一员工ID数量

问题分析

你已经实现了当月唯一员工ID数量的计算,但直接使用滚动窗口(rolling)无法正确计算过去3个月的唯一员工数——因为rolling.nunique()会对窗口内的"当月唯一数"做去重,而我们需要的是过去3个月所有员工ID的并集的数量。

数据预处理

首先确保日期列是datetime类型,并生成月份周期列DateM:

import pandas as pd

# 加载并预处理数据
df = pd.read_csv("你的数据文件路径.csv")
df['Date'] = pd.to_datetime(df['Date'])
df['DateM'] = df['Date'].dt.to_period('M')

方法一:直观的区间筛选法(适合中小数据量)

该方法通过为每个月份筛选过去3个月的所有员工ID,再计算去重数量:

  1. 提取员工与月份的唯一对应关系:避免同一个员工当月多次出现影响结果
emp_month_pairs = df[['EmpId', 'DateM']].drop_duplicates()
  1. 生成连续的月份序列:确保没有缺失月份导致计算断档
all_months = pd.period_range(
    start=emp_month_pairs['DateM'].min(),
    end=emp_month_pairs['DateM'].max(),
    freq='M'
)
  1. 定义函数计算单月对应的过去3个月唯一员工数
def calc_3month_unique(month):
    # 计算窗口起始月份(当前月往前推2个月,共3个月)
    start_month = month - 2
    # 筛选窗口内的所有员工ID并去重计数
    window_emps = emp_month_pairs[emp_month_pairs['DateM'].between(start_month, month)]['EmpId']
    return window_emps.nunique()
  1. 合并当月与过去3个月的结果
# 计算当月唯一员工数
monthly_unique = df.groupby("DateM")["EmpId"].nunique().reset_index()
monthly_unique.rename(columns={"EmpId": "One Month Unique EMP count"}, inplace=True)

# 计算过去3个月唯一员工数
three_month_unique = pd.DataFrame({
    'DateM': all_months,
    '3 Month Unique EMP count': all_months.map(calc_3month_unique)
})

# 合并并排序结果
final_result = pd.merge(monthly_unique, three_month_unique, on='DateM', how='left')
final_result = final_result.sort_values("DateM", ascending=False).reset_index(drop=True)

方法二:滚动窗口合并法(适合大数据量)

利用rolling窗口合并每月的员工列表,再计算并集大小:

  1. 生成包含所有连续月份的基础表
monthly_groups = df.groupby("DateM").agg(
    One_Month_Unique=("EmpId", "nunique"),
    Emp_List=("EmpId", "unique")
).reset_index()

# 补全缺失月份,避免窗口计算错误
all_months = pd.period_range(
    start=monthly_groups['DateM'].min(),
    end=monthly_groups['DateM'].max(),
    freq='M'
)
all_months_df = pd.DataFrame({'DateM': all_months})
monthly_full = pd.merge(all_months_df, monthly_groups, on='DateM', how='left').fillna({
    'One_Month_Unique': 0,
    'Emp_List': []
})
  1. 用滚动窗口合并员工列表并计算唯一数
# 滚动窗口大小为3(当前月+前2个月),合并窗口内的所有员工ID并去重计数
monthly_full['3_Month_Unique'] = monthly_full['Emp_List'].rolling(window=3).apply(
    lambda window: len(set().union(*window)),
    raw=False
)

# 整理最终结果
final_result = monthly_full[['DateM', 'One_Month_Unique', '3_Month_Unique']].rename(columns={
    'One_Month_Unique': 'One Month Unique EMP count',
    '3_Month_Unique': '3 Month Unique EMP count'
}).sort_values("DateM", ascending=False).reset_index(drop=True)

注意事项

  • 如果存在缺失月份,必须先补全连续月份,否则滚动窗口会计算错误(比如跳过缺失的月份,窗口实际包含的月份不足3个)
  • 两种方法的核心都是获取窗口内所有员工ID的并集,而不是对"当月唯一数"做二次去重

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:18:22