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

如何为DataFrame添加连续工作日序列长度统计列?

问题

现有一个包含Account(账户)和Date(日期)的DataFrame,需新增一列Length,统计每个账户下连续日期序列的长度(该连续日期段的总天数)。核心规则:

  • 常规连续日期(如01/02和01/03)算同一段连续序列
  • 周五到周一需视为连续日期(即跳过周末,周五和周一算作连续)

输入DataFrame

AccountDate
A01/01/2023
A01/02/2023
A01/03/2023
A01/05/2023
B01/02/2023
B01/03/2023
B01/05/2023
B01/06/2023
C01/01/2023
C01/02/2023
C01/04/2023
C01/05/2023
D01/01/2023
D01/05/2023
D01/07/2023
D01/08/2023
D01/09/2023
D01/10/2023

期望输出DataFrame

AccountDateLength
A01/01/20233
A01/02/20233
A01/03/20233
A01/05/20231
B01/02/20232
B01/03/20232
B01/05/20232
B01/06/20232
C01/01/20234
C01/02/20234
C01/04/20234
C01/05/20234
D01/01/20231
D01/05/20231
D01/07/20234
D01/08/20234
D01/09/20234
D01/10/20234
解决方案

使用Pandas可以高效实现需求,核心是自定义连续日期的判断逻辑,步骤如下:

import pandas as pd

# 构造输入DataFrame(若已有数据可跳过此步)
data = {
    'Account': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'D', 'D', 'D', 'D', 'D', 'D'],
    'Date': ['01/01/2023', '01/02/2023', '01/03/2023', '01/05/2023',
             '01/02/2023', '01/03/2023', '01/05/2023', '01/06/2023',
             '01/01/2023', '01/02/2023', '01/04/2023', '01/05/2023',
             '01/01/2023', '01/05/2023', '01/07/2023', '01/08/2023', '01/09/2023', '01/10/2023']
}
df = pd.DataFrame(data)

# 1. 转换日期格式并排序,确保每个账户内日期顺序正确
df['Date'] = pd.to_datetime(df['Date'], format='%m/%d/%Y')
df = df.sort_values(['Account', 'Date']).reset_index(drop=True)

# 2. 按账户分组,生成连续序列的分组ID
def mark_continuous_groups(group):
    # 计算当前日期与前一日的天数差
    day_diff = group['Date'].diff().dt.days
    # 判断是否连续:要么差1天,要么差3天且前一日是周五、当日是周一
    is_continuous = (day_diff == 1) | ((day_diff == 3) & 
                                       (group['Date'].shift(1).dt.weekday == 4) & 
                                       (group['Date'].dt.weekday == 0))
    # 非连续时分组ID累加,将连续日期归为同一组
    group['group_id'] = (~is_continuous).cumsum()
    return group

df = df.groupby('Account').apply(mark_continuous_groups).reset_index(drop=True)

# 3. 统计每个分组的长度,合并回原表
group_lengths = df.groupby(['Account', 'group_id']).size().reset_index(name='Length')
df = df.merge(group_lengths, on=['Account', 'group_id']).drop('group_id', axis=1)

# 可选:恢复日期为原字符串格式
df['Date'] = df['Date'].dt.strftime('%m/%d/%Y')

print(df)

关键逻辑说明

  • 日期转换与排序:先将日期转为datetime类型,确保后续差值计算准确,同时按账户和日期排序,避免因乱序导致分组错误
  • 连续判断规则:除了常规的1天差值,针对周五(weekday=4)到周一(weekday=0)的3天差值也判定为连续,符合需求
  • 分组与长度统计:通过cumsum()生成分组ID,将同一连续序列的日期归为一组,最后统计每组的长度并映射回原数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:47:54