Python Pandas如何新增列存储分组对应上月最后一天的Mark值
Pandas按Found分组匹配上月最后一天Mark值的代码调整方案
原有代码核心问题
- 日期转换逻辑错误:原数据日期格式为
日/月/年,未指定对应格式参数会导致日期解析错误,且重复执行两次日期转换属于冗余操作 - 缺少
BMonthEnd依赖导入,直接调用会报错 - 匹配逻辑错误:现有merge逻辑是匹配当前行所属月份最后一天的Mark值,和需求要求的「上月最后一天Mark值」不符
- 缺少上月最后一天日期和月末Mark值的映射关联步骤
调整后完整可运行代码
import pandas as pd from pandas.tseries.offsets import BMonthEnd # 导入工作日月末偏移类,若需自然月月末可替换为MonthEnd # 原始数据构造 df = pd.DataFrame({ 'Found':['A','A','A','A','A','B','B','B','B'], 'Date':['14/10/2021','19/10/2021','29/10/2021','30/09/2021','20/09/2021','20/10/2021','29/10/2021','15/10/2021','10/09/2021'], 'Mark':[1,2,3,4,3,1,2,3,2] }) # 1. 正确转换日期格式,指定输入为日/月/年格式 df['Date'] = pd.to_datetime(df['Date'], format='%d/%m/%Y') # 2. 计算每行日期对应当月最后工作日 df['current_month_last_day'] = df['Date'] + BMonthEnd(0) # 3. 计算每行日期对应上月最后工作日 df['prev_month_last_day'] = df['Date'] - BMonthEnd(1) # 4. 构造月末Mark映射表:每个Found+月末日期对应的Mark值 month_end_mark_map = df[df['Date'] == df['current_month_last_day']][['Found', 'current_month_last_day', 'Mark']].rename( columns={'current_month_last_day': 'map_month_last_day', 'Mark': 'prev_month_last_mark'} ) # 5. 左关联映射表,匹配上月最后一天的Mark值 df = df.merge( month_end_mark_map, left_on=['Found', 'prev_month_last_day'], right_on=['Found', 'map_month_last_day'], how='left' ).drop(columns=['map_month_last_day']) # 删除冗余的关联字段 print(df)
逻辑补充说明
- 如果你需要匹配自然月最后一天而非工作日最后一天,把所有
BMonthEnd替换为MonthEnd即可 - 若某个Found分组的上月月末无对应记录,关联后
prev_month_last_mark字段会自动填充为NaN,你可以按需用fillna方法填充默认值 - 若同一Found的同一个月末有多个Mark记录,构造
month_end_mark_map时可以先分组排序后取指定值,比如按Date降序取第一条:
month_end_mark_map = df[df['Date'] == df['current_month_last_day']].sort_values('Date', ascending=False).groupby(['Found', 'current_month_last_day']).head(1)[['Found', 'current_month_last_day', 'Mark']].rename( columns={'current_month_last_day': 'map_month_last_day', 'Mark': 'prev_month_last_mark'} )
内容的提问来源于stack exchange,提问作者Eric Alves
相关产品推荐
相关产品推荐

