如何为学生数学竞赛数据集添加Last_win列,获取上次夺冠Race_ID
解决方案:为学生竞赛数据集添加
Last_win列 问题描述
现有一份按日期降序排列的学生数学竞赛数据集,需新增Last_win列,返回该学生上次(更早的竞赛中)获得Rank 1时的Race_ID,无历史夺冠记录则显示NaN。
原始数据集
Race_ID Date Student_ID Rank 21 1/1/2023 1 3 21 1/1/2023 2 2 21 1/1/2023 3 1 21 1/1/2023 4 4 25 11/9/2022 1 2 25 11/9/2022 2 3 25 11/9/2022 3 1 3 17/4/2022 5 4 3 17/4/2022 2 1 3 17/4/2022 3 2 3 17/4/2022 4 3 14 1/3/2022 1 1 14 1/3/2022 2 2 85 1/1/2021 1 2 85 1/1/2021 2 3 85 1/1/2021 3 1
预期输出
Race_ID Date Student_ID Rank Last_win 21 1/1/2023 1 3 14 21 1/1/2023 2 2 3 21 1/1/2023 3 1 25 21 1/1/2023 4 4 NaN 25 11/9/2022 1 2 14 25 11/9/2022 2 3 3 25 11/9/2022 3 1 85 3 17/4/2022 5 4 NaN 3 17/4/2022 2 1 NaN 3 17/4/2022 3 2 85 3 17/4/2022 4 3 NaN 14 1/3/2022 1 1 NaN 14 1/3/2022 2 2 NaN 85 1/1/2021 1 2 NaN 85 1/1/2021 2 3 NaN 85 1/1/2021 3 1 NaN
实现代码(Pandas)
针对大型数据集,采用分组+窗口填充的高效方法:
import pandas as pd # 读取数据集(若未读取,可替换为pd.read_csv等方法) # df = pd.read_csv('your_dataset.csv') # 转换Date列为datetime类型,匹配原始数据的日/月/年格式 df['Date'] = pd.to_datetime(df['Date'], format='%d/%m/%Y') # 定义分组处理逻辑 def add_last_win(group): # 仅保留Rank=1对应的Race_ID,其余设为NaN win_races = group['Race_ID'].where(group['Rank'] == 1) # 向下移位获取更早的竞赛记录,再向后填充得到最近的历史夺冠Race_ID group['Last_win'] = win_races.shift(-1).bfill() return group # 应用分组处理 df = df.groupby('Student_ID', group_keys=False).apply(add_last_win) # 查看结果(可选) print(df)
代码说明
groupby('Student_ID'):按学生分组,确保仅在同一学生的竞赛记录中查找历史夺冠记录;where(group['Rank'] == 1):过滤出该学生所有夺冠的竞赛ID;shift(-1):将夺冠ID向下移动一行,对应当前行之后(更早)的竞赛记录;bfill():向后填充NaN,自动找到当前行之后最近的夺冠ID,无记录则保留NaN。
内容的提问来源于stack exchange,提问作者Apook
相关产品推荐
相关产品推荐

