Python处理节假日日期计算时如何减少冗余if条件判断
优化方案
通过星期偏移规则映射表可以完全消除冗余的if/elif分支,同时原逐行遍历DataFrame的写法效率很低,推荐直接用pandas原生的向量化日期运算,性能和可维护性都会提升很多。
首先梳理原代码中每个星期对应的偏移规则(weekday()返回值0为周一、6为周日),统一存在字典中维护,不需要写分支判断:
| 星期 | weekday值 | 节前基准日偏移(天) | 节后基准日偏移(天) | 节后6周偏移方向 |
|---|---|---|---|---|
| 周一 | 0 | -3 | +1 | 减6周 |
| 周二 | 1 | -1 | +1 | 加6周 |
| 周三 | 2 | -1 | +1 | 加6周 |
| 周四 | 3 | -1 | +1 | 加6周 |
| 周五 | 4 | -1 | +3 | 减6周 |
| 周六 | 5 | -1 | +2 | 减6周 |
| 周日 | 6 | -2 | +1 | 加6周 |
注:原代码周六分支存在笔误:定义变量为
pre,计算preWeek时误用preDay会触发变量未定义错误,以下实现已修复该问题。
实现1:保留原有列表生成逻辑(最小改动)
只替换分支判断部分,原有代码结构不变:
import datetime PreList = [] DuringList = [] PostList = [] # 偏移规则映射表,格式:(节前天数偏移, 节后天数偏移, 节后周偏移系数:-1为减6周,1为加6周) weekday_offset = { 0: (-3, 1, -1), 1: (-1, 1, 1), 2: (-1, 1, 1), 3: (-1, 1, 1), 4: (-1, 3, -1), 5: (-1, 2, -1), 6: (-2, 1, 1) } for i in range(len(df)): cur_date = df.date[i] pre_d, post_d, post_sign = weekday_offset[cur_date.weekday()] pre_week = cur_date + datetime.timedelta(days=pre_d, weeks=-6) during = cur_date post_week = cur_date + datetime.timedelta(days=post_d, weeks=6*post_sign) PreList.append(pre_week) DuringList.append(during) PostList.append(post_week) # 直接赋值为df新列即可 df['pre_date'] = PreList df['during_date'] = DuringList df['post_date'] = PostList
实现2:pandas向量化实现(推荐,性能最优)
不需要写任何循环,利用pandas原生日期运算处理,数据量越大性能优势越明显:
import pandas as pd # 先确保日期列是datetime格式 df['date'] = pd.to_datetime(df['date']) weekday_offset = { 0: (-3, 1, -1), 1: (-1, 1, 1), 2: (-1, 1, 1), 3: (-1, 1, 1), 4: (-1, 3, -1), 5: (-1, 2, -1), 6: (-2, 1, 1) } # 批量匹配每个日期对应的偏移参数 offset_params = df['date'].dt.weekday.map(weekday_offset).apply(pd.Series) offset_params.columns = ['pre_off', 'post_off', 'post_sign'] # 向量化计算所有日期 df['during_date'] = df['date'] df['pre_date'] = df['date'] + pd.to_timedelta(offset_params['pre_off'], unit='d') - pd.Timedelta(weeks=6) df['post_date'] = df['date'] + pd.to_timedelta(offset_params['post_off'], unit='d') + pd.Timedelta(weeks=6) * offset_params['post_sign']
优化点说明
- 所有规则统一在映射字典中维护,后续要调整偏移天数/方向只需要改字典值,不需要修改业务逻辑代码
- 完全消除冗余分支,代码行数减少近60%,没有重复的append、timedelta调用
- 修复了原代码的变量名笔误
- 向量化实现比逐行循环快1~2个数量级,适合处理大规模节假日数据
内容的提问来源于stack exchange,提问作者user131638
相关产品推荐
相关产品推荐

