如何修改从pandas DataFrame获取的切片/Series的日期年份
我手头有一份团队导入的跨多年排班数据集,我已经完成了数据清洗,将宽表转为了长表,但遇到了一个问题。
数据说明
year和period从拆分的工作表名称中获取,均为字符串类型。week为一年中的周数,从排班表中提取,浮点型。date从字符串转换而来,专门写了函数处理荷兰语格式的日期并做标准化,原始日期无年份信息,因此使用了第一列的年份填充,处理后为datetime格式。shift为班次类型:S1对应早班,S2对应晚班,S3对应夜班。- 每条记录对应一名员工,出于隐私考虑,姓名已做抹除处理。
- 写了一个类,包含多个方法用于适配政府对排班的相关强制规定。

遇到的问题
可以看到1137、1138号条目对应的日期应该属于2022年,请问怎么才能便捷修改这些日期的年份?我尝试过写如下代码:
for week, date in prepocessed_data_merged[['week', 'date']].values: # There are always more than 52 weeks in a year. # If the month of the date in week 52 is 1 (Jan), then something is wrong. if (week == 52) & (date.month == 1): prepocessed_data_merged.loc[(prepocessed_data_merged['week'] == week) & (prepocessed_data_merged['date']), 'date'] = ???
但正如预期的那样,筛选后返回的是一个Series,因为单日对应3个班次,也就是同个日期有3条记录需要修改年份。请问要如何对选中的Series/切片执行年份修改,同时同步更新到原DataFrame中?
我知道可以用:dt.replace(year=current_year+1),但要怎么对preprocessed_data DataFrame中筛选出的Series执行这个replace操作?
解决方案
不需要循环遍历,直接用pandas向量化操作即可批量处理符合条件的所有行:
- 先构造布尔掩码筛选出需要修改的行
- 对筛选出的
date列批量执行年份+1操作,修改会直接同步到原DataFrame
写法1:用replace实现(逻辑更直观)
import pandas as pd # 筛选条件:周数为52 且 日期月份为1月 mask = (prepocessed_data_merged['week'] == 52) & (prepocessed_data_merged['date'].dt.month == 1) # 对符合条件的日期批量修改年份 prepocessed_data_merged.loc[mask, 'date'] = prepocessed_data_merged.loc[mask, 'date'].apply(lambda x: x.replace(year=x.year + 1))
写法2:用DateOffset实现(性能更高,适配闰年特殊日期)
如果遇到2月29日这类闰年独有日期,第一种replace方法会报错,用DateOffset会自动将日期调整为2月28日:
mask = (prepocessed_data_merged['week'] == 52) & (prepocessed_data_merged['date'].dt.month == 1) prepocessed_data_merged.loc[mask, 'date'] = prepocessed_data_merged.loc[mask, 'date'] + pd.offsets.DateOffset(years=1)
内容的提问来源于stack exchange,提问作者Kars
相关产品推荐
相关产品推荐

