You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas DataFrame中生成记录学生上次前三排名预测分数的新列

问题描述

现有一个按日期降序排列的DataFrame,记录学生班级排名(Rank)和预测分数(Predicted_Score),数据如下:

Date        Student_ID  Rank    Predicted_Score
4/7/2021    33          2       87
13/6/2021   33          4       88
31/3/2021   33          7       88
28/2/2021   33          2       86
14/2/2021   33          10      86
31/1/2021   33          8       86
23/12/2020  33          1       81
8/11/2020   33          3       80
21/10/2020  33          3       80
23/9/2020   33          4       80
20/5/2020   33          3       80
29/4/2020   33          4       80
15/4/2020   33          2       79
26/2/2020   33          3       79
12/2/2020   33          5       79
29/1/2020   33          1       70

需要新增一列Recent_Predicted_Score,记录该学生上次进入班级前三(Rank为1、2、3)时的Predicted_Score,期望结果如下:

Date        Student_ID  Rank    Predicted_Score    Recent_Predicted_Score
4/7/2021    33          2       87                 86
13/6/2021   33          4       88                 86
31/3/2021   33          7       88                 86
28/2/2021   33          2       86                 81
14/2/2021   33          10      86                 81
31/1/2021   33          8       86                 81
23/12/2020  33          1       81                 80
8/11/2020   33          3       80                 80
21/10/2020  33          3       80                 80
23/9/2020   33          4       80                 80
20/5/2020   33          3       80                 79
29/4/2020   33          4       80                 79
15/4/2020   33          2       79                 79
26/2/2020   33          3       79                 70
12/2/2020   33          5       79                 70
29/1/2020   33          1       70

尝试过以下代码但未成功:

df.sort_values(by = ['Student_ID', 'Date'], ascending = [True, False], inplace = True)
lp1 = df['Predicted_Score'].where(df['Rank'].isin([1,2,3])).groupby(df['Student_ID']).bfill()
lp2 = df.groupby(['Student_ID', 'Rank'])['Predicted_Score'].shift(-1)
df = df.assign(Recent_Predicted_Score=lp1.mask(df['Rank'].isin([1,2,3]), lp2))
解决方案

核心思路:先标记所有前三记录的分数,再按日期降序获取每条记录的上一个前三分数,最后用向前填充补全非前三记录的空缺。

完整实现代码

# 确保数据按Student_ID和Date降序排列(原数据已满足可跳过)
df.sort_values(by=['Student_ID', 'Date'], ascending=[True, False], inplace=True)

# 1. 仅保留前三记录的Predicted_Score,其余设为NaN
df['temp_score'] = df['Predicted_Score'].where(df['Rank'].isin([1,2,3]))

# 2. 按学生分组,将前三分数向下偏移一位,得到每条记录的上一个前三分数
df['Recent_Predicted_Score'] = df.groupby('Student_ID')['temp_score'].shift(1)

# 3. 向前填充,让非前三记录继承上一条的Recent_Predicted_Score
df['Recent_Predicted_Score'] = df.groupby('Student_ID')['Recent_Predicted_Score'].ffill()

# 4. 删除临时列
df.drop('temp_score', axis=1, inplace=True)

逻辑说明

  • 步骤1:用where筛选出前三记录的分数,其他记录标记为空白,方便后续定位有效数据
  • 步骤2:shift(1)将每个学生的前三分数向下移动一行,正好对应当前记录的上次前三分数
  • 步骤3:ffill()向前填充,解决非前三记录没有对应上次分数的问题,让它们延续上一条记录的结果
  • 最终最早的记录(29/1/2020)因为没有更早的前三数据,Recent_Predicted_Score会保持为空,符合示例要求

内容的提问来源于stack exchange,提问作者Apook

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:59:20