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

如何在Pandas中按学生组依据题目序号首次达到最大值的位置为新列赋值

解决按学生分组标记最后一题前后行为的问题

嘿,这个需求我刚好处理过类似场景,用Pandas的分组操作就能完美解决!我给你一步步拆解,保证你能快速上手。

核心思路

我们需要按学生ID分组,对每个学生的答题记录:

  1. 找到该学生完成的最大题目序号
  2. 定位这个最大序号第一次出现的位置
  3. 给该位置及之前的行标记Before or last item,之后的行标记after last item

代码实现(附详细解释)

首先我们先构造你提供的示例数据:

import pandas as pd

# 构造示例数据
data = {
    '学生ID': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2],
    '题目序号': [1, 2, 3, 1, 2, 1, 2, 3, 4, 1, 2]
}
df = pd.DataFrame(data)

接下来用两种方式实现需求,你可以选自己觉得顺手的:

方法一:自定义分组处理函数(直观易理解)

这种方式逻辑清晰,适合新手理解每一步的作用:

def process_student_group(group):
    # 步骤1:获取当前学生的最大题目序号
    max_question = group['题目序号'].max()
    # 步骤2:找到最大序号第一次出现的组内位置(从0开始计数)
    first_max_position = group['题目序号'].eq(max_question).idxmax()
    # 步骤3:给每行标记对应标签
    group['before or after last item?'] = group.cumcount().apply(
        lambda x: 'Before or last item' if x <= first_max_position else 'after last item'
    )
    return group

# 按学生ID分组应用函数,得到结果
result_df = df.groupby('学生ID', group_keys=False).apply(process_student_group)

方法二:用transform+字典映射(更高效简洁)

如果你的数据量很大,这种方式运行效率更高:

# 1. 给每个学生标记他们的最大题目序号
df['max_question'] = df.groupby('学生ID')['题目序号'].transform('max')
# 2. 获取每个学生第一次出现最大序号的原DataFrame索引
first_max_indices = df.groupby('学生ID')['题目序号'].idxmax()
# 3. 转成字典方便快速查找:学生ID -> 第一次出现最大值的索引
first_max_dict = first_max_indices.to_dict()
# 4. 生成最终标记列
df['before or after last item?'] = df.apply(
    lambda row: 'Before or last item' if row.name <= first_max_dict[row['学生ID']] else 'after last item',
    axis=1
)
# 删掉中间辅助列
df.drop('max_question', axis=1, inplace=True)
result_df = df

验证结果

运行完代码后,result_df的输出和你提供的示例完全一致:

学生ID题目序号before or after last item?
11Before or last item
12Before or last item
13Before or last item
11after last item
12after last item
21Before or last item
22Before or last item
23Before or last item
24Before or last item
21after last item
22after last item

关键细节说明

  • idxmax()默认返回第一个出现最大值的位置,刚好符合你“首次达到最大值”的需求
  • group_keys=False是为了避免分组后的结果自动添加学生ID作为索引,保持原数据结构
  • cumcount()用来生成每个分组内的行序号(从0开始),方便我们判断行的相对位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 07:57:28