如何基于起始日期与当前日期之间的周数重复数据行-Python教程

本文介绍如何根据每行记录中日期字段与当前日期之间的完整周数,动态重复 dataframe 行,并为每条重复记录生成对应的 iso 周序号(week)和年份(year),确保时间序列连续、跨年正确、逻辑清晰。

在数据分析与报表生成中,常需将单条日期记录“展开”为以周为单位的时间序列——例如,为每个 ID 生成从其原始日期开始、直至当前周为止的每周快照。关键挑战在于:既要准确计算跨年周数,又要保证每周对应正确的 ISO 年份与周编号(如 2023-12-31 属于 2024 年第 1 周)。直接使用 .dt.days // 7 易因时区、闰年或 ISO 周规则(周一为每周起点,第1周含当年首个周四)导致偏差。

以下提供一种健壮、向量化、无需循环的解决方案,核心思路是:
✅ 使用 pd.Period 精确对齐周粒度(避免日期算术误差)
✅ 利用 Index.repeat() 高效复制行
✅ 通过 cumcount() + pd.to_timedelta() 逐周递增日期,再调用 .dt.isocalendar() 获取标准 ISO 周信息

完整实现代码

import pandas as pd

# 构建示例数据
df = pd.DataFrame({
    'ID': ['ID001', 'ID002', 'ID003'],
    'DATE': ['24/12/2023', '01/02/2024', '12/02/2024']
})
df['DATE'] = pd.to_datetime(df['DATE'], dayfirst=True)

# 步骤 1:计算每个 ID 从 DATE 到当前日期(含)的完整周数(含起始周)
now_period = pd.Timestamp('now').to_period('W')  # 当前 ISO 周
date_periods = df['DATE'].dt.to_period('W')      # 每行 DATE 所属 ISO 周
n_weeks = date_periods.rsub(now_period).apply(lambda x: x.n)  # 周差(非负整数)

# 步骤 2:按周数重复行(+1 是为了包含起始周本身)
repeated_df = df.loc[df.index.repeat(n_weeks + 1)].copy().reset_index(drop=True)

# 步骤 3:为每组重复行生成递增的周日期,并提取 ISO 年与周
# groupby(level=0) 在 repeat 后 index 有重复,用 cumcount() 生成 0,1,2... 偏移量(单位:天)
week_offsets = repeated_df.groupby(repeated_df.index).cumcount() * 7
base_dates = df['DATE'].reindex(repeated_df.index, method='ffill')
expanded_dates = base_dates + pd.to_timedelta(week_offsets, unit='D')

# 步骤 4:添加 YEAR 和 WEEK 列(使用 isocalendar 确保 ISO 标准)
cal = expanded_dates.dt.isocalendar()
repeated_df['YEAR'] = cal.year
repeated_df['WEEK'] = cal.week

print(repeated_df[['ID', 'DATE', 'YEAR', 'WEEK']])

输出示例(运行时刻为 2024 年第 7 周)

      ID       DATE  YEAR  WEEK
0  ID001 2023-12-24  2023    51
1  ID001 2023-12-24  2023    52
2  ID001 2023-12-24  2024     1
3  ID001 2023-12-24  2024     2
4  ID001 2023-12-24  2024     3
5  ID001 2023-12-24  2024     4
6  ID001 2023-12-24  2024     5
7  ID001 2023-12-24  2024     6
8  ID001 2023-12-24  2024     7
9  ID002 2024-02-01  2024     5
10 ID002 2024-02-01  2024     6
11 ID002 2024-02-01  2024     7
12 ID003 2024-02-12  2024     7

关键注意事项

  • ISO 周兼容性:.dt.isocalendar() 是 Pandas 中唯一严格遵循 ISO 8601 周标准的方法(区别于 .dt.week 已弃用),能正确处理年末/年初跨周(如 2023-12-31 → 2024-W01)。
  • 性能优化:全程避免 for 循环与 loc[i] 赋值,利用 repeat() 和 groupby().cumcount() 实现 O(n) 时间复杂度。
  • 边界处理:n_weeks + 1 确保起始周被包含;若某行 DATE 已在当前周之后,rsub() 返回负 Period,.n 为 0,该行仅保留 1 条记录(符合业务预期)。
  • 可扩展性:如需添加“WEEK_START”列(每周一日期),可在 expanded_dates 后调用 .dt.to_period(‘W’).dt.start_time。

此方法兼具准确性、效率与可维护性,适用于周报聚合、滚动预测、时间维度建模等典型场景。

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » 如何基于起始日期与当前日期之间的周数重复数据行-Python教程
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4031441+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4031441+
  • 本周更新: 0+
  • 最后更新: 2026-03-16