Pandas按分组新增列获取上月对应Mark值的实现方法咨询
实现DataFrame新增上月最高Mark值列方案
首先修正你现有代码的两处问题:
- 重复调用
pd.to_datetime处理Date列属于冗余操作,仅需调用一次即可 - 原日期转换的
format参数配置错误,你的输入日期为日/月/年格式,对应格式串应为%d/%m/%Y,否则会解析异常
完整实现步骤如下:
步骤1:导入依赖、构造数据、生成基准日期字段
import pandas as pd from pandas.tseries.offsets import BMonthEnd 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/09/2021','30/09/2021'], 'Mark':[1,2,3,4,3,1,2,5,8] }) # 日期格式转换 df['Date'] = pd.to_datetime(df['Date'], format='%d/%m/%Y') # 计算当前日期所属月份的最后一个工作日 df['LastDay'] = df['Date'] - BMonthEnd(0) # 生成上月最后一个工作日字段,用于关联上月的最高Mark值 df['PrevMonthLastDay'] = df['LastDay'] - BMonthEnd(1)
步骤2:构造「主体+月份」对应最高Mark值的映射表
# 按主体、月份分组取最高Mark对应的行 mark_last_day = df.loc[df.groupby(['Found', 'LastDay'])['Mark'].idxmax()] # 重命名字段,适配关联上月的逻辑 mark_month_map = mark_last_day[['Found', 'LastDay', 'Mark']].rename(columns={'Mark': 'Mark_PrevMonth'})
步骤3:关联得到上月最高Mark值
df = df.merge( mark_month_map, left_on=['Found', 'PrevMonthLastDay'], right_on=['Found', 'LastDay'], how='left' # 清理关联产生的冗余列 ).drop(columns=['LastDay_y']).rename(columns={'LastDay_x':'LastDay'})
步骤4(可选):合并当月最高Mark值(你原有需求)
df = df.merge( mark_last_day[['Found', 'LastDay', 'Mark']], on=['Found', 'LastDay'], how='left', suffixes=['', '_LastDay'] )
效果说明:所有10月的行都会匹配到对应主体9月的最高Mark值,9月的行因为没有上月数据,对应Mark_PrevMonth字段为NaN,和手动填充的预期效果完全一致。
内容的提问来源于stack exchange,提问作者Eric Alves
相关产品推荐
相关产品推荐

