如何使用Python Pandas为日期数据添加每月周数标识列?
给Pandas DataFrame添加当月周数标识列
给定仅包含Date列的Pandas DataFrame,需要新增一列Week,格式为WeekX_月份缩写(例如2022-10-04对应Week1_Oct),输入输出示例如下:
输入
| Date |
|---|
| 2022-10-04 |
| 2022-10-04 |
| 2022-10-06 |
| 2022-10-12 |
| 2022-10-19 |
| 2022-10-25 |
| 2022-10-31 |
| 2022-11-02 |
| 2022-11-03 |
期望输出
| Date | Week |
|---|---|
| 2022-10-04 | Week1_Oct |
| 2022-10-04 | Week1_Oct |
| 2022-10-06 | Week1_Oct |
| 2022-10-12 | Week1_Oct |
| 2022-10-19 | Week2_Oct |
| 2022-10-25 | Week3_Oct |
| 2022-10-31 | Week4_Oct |
| 2022-11-02 | Week1_Nov |
| 2022-11-03 | Week1_Nov |
实现方法
1. 先确保Date列为datetime类型
首先必须把Date列转换成datetime格式,否则无法使用Pandas的日期处理工具:
import pandas as pd # 假设你的DataFrame名为df df['Date'] = pd.to_datetime(df['Date'])
2. 计算周数与月份缩写
通用方案:按每月7天周期划分(最常用)
如果你的周数规则是每月1-7号为Week1,8-14号为Week2,以此类推,用下面的代码:
# 计算当月周数:(日期-1)//7 +1 实现每7天一个周期 df['Week'] = 'Week' + ((df['Date'].dt.day - 1) // 7 + 1).astype(str) + '_' + df['Date'].dt.strftime('%b')
不过这个方案得到的10月12号会是Week2,和示例不符,说明示例的周数规则是自定义的。
匹配示例的自定义方案
观察示例的周数分界:10月19日才进入Week2,25日进入Week3,31日进入Week4,推测是按自定义的日期区间划分周数。如果要完全匹配示例结果,可以用日期区间赋值:
# 定义各周的日期范围和对应的标签 week_ranges = [ (pd.to_datetime('2022-10-01'), pd.to_datetime('2022-10-18'), 'Week1_Oct'), (pd.to_datetime('2022-10-19'), pd.to_datetime('2022-10-24'), 'Week2_Oct'), (pd.to_datetime('2022-10-25'), pd.to_datetime('2022-10-30'), 'Week3_Oct'), (pd.to_datetime('2022-10-31'), pd.to_datetime('2022-10-31'), 'Week4_Oct'), (pd.to_datetime('2022-11-01'), pd.to_datetime('2022-11-07'), 'Week1_Nov'), ] # 初始化Week列 df['Week'] = '' # 遍历区间赋值 for start, end, label in week_ranges: df.loc[(df['Date'] >= start) & (df['Date'] <= end), 'Week'] = label
另一种通用方案:按ISO周重新编号
如果你的周数规则是以周一为周起始,当月第一个完整ISO周为Week1,可以用下面的代码:
# 获取每个日期的ISO周数 df['iso_week'] = df['Date'].dt.isocalendar().week # 按年月分组,得到每组的最小ISO周数(当月第一个ISO周) df['month_min_week'] = df.groupby([df['Date'].dt.year, df['Date'].dt.month])['iso_week'].transform('min') # 计算当月周数,拼接成目标格式 df['Week'] = 'Week' + (df['iso_week'] - df['month_min_week'] + 1).astype(str) + '_' + df['Date'].dt.strftime('%b') # 清理中间列 df = df.drop(['iso_week', 'month_min_week'], axis=1)
内容的提问来源于stack exchange,提问作者nat
相关产品推荐
相关产品推荐

