如何使用Pandas生成多年周日期范围并解决周数匹配异常问题
问题原因
你代码的核心问题是ISO周对应的年份和公历年并不完全重合。dt.isocalendar()返回的week字段是ISO周数,对应的是ISO年(不是公历年):每年的第一个ISO周要求包含当年的第一个周四,因此每年年初的1-3天可能属于上一年的最后一个ISO周,年末的1-3天也可能属于下一年的第一个ISO周。你之前提取年份用的是dt.year(公历年),和ISO周不匹配,才会出现2017-01-01标注为2017年第52周的错位问题。
解决方案
你可以根据自己的需求选择以下两种规则统一的方案:
方案1:遵循ISO周规则(周起始为周一)
直接提取isocalendar返回的ISO年作为年份字段,和ISO周数匹配即可,不会出现跨年错位:
import pandas as pd all_weeks_generated = pd.DataFrame() # freq='W'默认是每周日为周期结束日期,要改为周一周末的话可替换为'W-MON' all_weeks_generated['week_dt'] = pd.date_range(start = '2001-01-01', end = '2021-09-13', freq='W') # 一次性提取ISO规则的年、周信息 iso_cal = all_weeks_generated['week_dt'].dt.isocalendar() all_weeks_generated['week'] = iso_cal.week all_weeks_generated['year'] = iso_cal.year
修改后再筛选2017年第52周,只会返回2017-12-31的结果,不会再出现2017年1月1日的错误条目。
方案2:自定义公历年周规则(无ISO跨年问题)
如果你不想用ISO周规则,要求周数完全归属公历年,可通过strftime的周数格式化参数实现:
- 周起始为周日:用
%U参数,每年1月1日所在周为第1周 - 周起始为周一:用
%W参数,每年1月1日所在周为第1周
示例代码(周起始为周日):
all_weeks_generated = pd.DataFrame() # freq设置为和周规则匹配的周期结束日期,这里W-SUN对应周日为周最后一天 all_weeks_generated['week_dt'] = pd.date_range(start = '2001-01-01', end = '2021-09-13', freq='W-SUN') all_weeks_generated['week'] = all_weeks_generated['week_dt'].dt.strftime('%U').astype(int) all_weeks_generated['year'] = all_weeks_generated['week_dt'].dt.year
该方案下所有周数完全归属对应公历年,不会出现跨年周的问题。
日度数据匹配方法
给日度数据匹配对应周日期时,对日度日期执行和周表完全一致的年、周字段计算逻辑,再通过年+周两个字段做关联合并即可,规则完全统一后DARTs可正常识别时间序列。
内容的提问来源于stack exchange,提问作者Joshua Noble
相关产品推荐
相关产品推荐

