用.dt accessor可向量化提取年月日周几等字段,避免循环;需先转datetime类型;节假日判断须用holidays库,注意其不支持调休上班日及农历节日。

用 dt 访问器批量提取年月日周几,别用循环
直接对 pd.Series(类型是 datetime64[ns])调用 .dt 属性,就能向量化获取时间字段。循环遍历每个时间点再取 .year 之类,慢且易错。
- 确保列是 datetime 类型:用
pd.to_datetime(df['time_col'])强制转换,否则.dt会报AttributeError: Can only use .dt accessor with datetimelike values -
.dt.year、.dt.month、.dt.day返回整数;.dt.dayofweek周一为 0、周日为 6;.dt.weekday_name在 pandas 1.0+ 已弃用,改用.dt.day_name() - 注意时区:若原始数据带时区(如
UTC),.dt.date可能返回本地时区日期,建议统一用.dt.tz_localize(None)或.dt.tz_convert('Asia/Shanghai')对齐
节假日标识不能靠 pandas 自带,得用 holidays 库
pandas 没有内置节假日判断逻辑,.dt 也提供不了「是否节假日」字段。必须引入第三方库,最常用的是 holidays。
- 安装:
pip install holidays,注意它不包含中国农历节日(如春节假期),默认只支持法定调休日框架 - 用法示例:
cn_holidays = holidays.China(years=[2023, 2024]),然后用df['time_col'].dt.date.map(cn_holidays)得到字符串(如'Spring Festival')或None - ⚠️ 坑:
holidays.China()返回的是公历节假日,但中国实际放假常含调休工作日(如节前周末上班),该库不标记「调休上班日」,需额外维护一张工作日表或用workalendar
dt.isocalendar() 比 dt.week 更可靠
想按 ISO 周(周一为每周第一天,第 1 周含当年第一个周四)分组?别用已弃用的 .dt.week,它在 pandas 2.0+ 报错。
- 正确写法:
df['time_col'].dt.isocalendar().week,返回Int64Index,可直接参与分组或特征工程 -
.isocalendar()同时返回year、week、day三列,适合构造「2024-W05-Mon」这类复合标识 - 性能影响小,但注意:ISO 周年份可能和日历年份不同(例如 2024-01-01 是周一,属 2024 年第 1 周;而 2023-12-31 是周日,却属于 2024 年第 1 周)
批量处理时,避免在循环里反复调用 holidays 实例
如果对每行单独查 cn_holidays.get(date),10 万行可能卡住——不是因为逻辑错,而是字典查找没批量优化。
立即学习“Python免费学习笔记(深入)”;
- 正确做法:先用
df['date_only'] = df['time_col'].dt.date提取出日期序列,再一次性.map()到 holidays 实例 - 更稳方案:把
holidays.China(years=...)转成 dict,如holidays_dict = {d: name for d, name in cn_holidays.items()},再用.map(holidays_dict),避免每次触发内部迭代 - 容易忽略的一点:
holidays默认只加载当前年及前后一年,跨多年数据务必显式传入years=list(range(2020, 2025))










