如何为时间序列DataFrame生成月首个/最后一个工作日特征?
问题描述
我有一个包含Date、temp_data、holiday、day列的DataFrame,数据示例如下:
Date temp_data holiday day 01.01.2000 10000 0 1 02.01.2000 0 1 2 03.01.2000 2000 0 3 .. .. .. 30.01.2000 200 0 30 31.01.2000 0 1 31 01.02.2000 0 1 1 02.02.2000 2500 0 2
其中holiday=0代表工作日(有数据),holiday=1代表非工作日(无数据)。需要新增两列first_working_day_of_month和last_working_day_of_month,最终DataFrame格式如下:
Date temp_data holiday day first_wd_of_month last_wd_of_month 01.01.2000 10000 0 1 1 0 02.01.2000 0 1 2 0 0 03.01.2000 2000 0 3 0 0 .. .. .. 30.01.2000 200 0 30 0 1 31.01.2000 0 1 31 0 0 01.02.2000 0 1 1 0 0 02.02.2000 2500 0 2 1 0
解决方案
可以用Pandas的分组和布尔索引实现,步骤如下:
- 转换日期格式:先把
Date列转为datetime类型,方便按月份分组处理
import pandas as pd # 转换Date列为datetime格式 df['Date'] = pd.to_datetime(df['Date'], format='%d.%m.%Y')
- 筛选并分组工作日:提取所有工作日数据,按年-月分组后获取每月的第一个和最后一个工作日日期
# 筛选出所有工作日 working_days = df[df['holiday'] == 0] # 按年和月分组,获取每月首尾工作日的日期 first_wd = working_days.groupby([working_days['Date'].dt.year, working_days['Date'].dt.month])['Date'].first() last_wd = working_days.groupby([working_days['Date'].dt.year, working_days['Date'].dt.month])['Date'].last()
- 生成目标列:通过日期匹配标记每行是否为当月首尾工作日
# 初始化新列为0 df['first_wd_of_month'] = 0 df['last_wd_of_month'] = 0 # 匹配第一个工作日,标记为1 df.loc[df['Date'].isin(first_wd), 'first_wd_of_month'] = 1 # 匹配最后一个工作日,标记为1 df.loc[df['Date'].isin(last_wd), 'last_wd_of_month'] = 1
- 可选:恢复原日期格式:如果需要把
Date列转回初始的字符串格式
df['Date'] = df['Date'].dt.strftime('%d.%m.%Y')
简化版代码
如果想更紧凑,可以合并步骤:
import pandas as pd df['Date'] = pd.to_datetime(df['Date'], format='%d.%m.%Y') # 分组获取每月首尾工作日 wd_groups = df[df['holiday'] == 0].groupby([df['Date'].dt.year, df['Date'].dt.month])['Date'] first_wd = wd_groups.first() last_wd = wd_groups.last() # 直接通过布尔值转整数生成目标列 df['first_wd_of_month'] = df['Date'].isin(first_wd).astype(int) df['last_wd_of_month'] = df['Date'].isin(last_wd).astype(int) # 可选转回原日期格式 df['Date'] = df['Date'].dt.strftime('%d.%m.%Y')
内容的提问来源于stack exchange,提问作者Bella_18
相关产品推荐
相关产品推荐

