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

Pandas基于file列判断学生是否重考生成新列时出现KeyError: 'file'的解决方法

解决KeyError: 'file'的问题并实现重考判断需求

问题原因

你遇到的KeyError: 'file'是因为在调用pivot_table时,把'file'放到了index参数里,这时候它不再是DataFrame的普通列,而是变成了**多层索引(MultiIndex)**的一部分。当你用apply遍历df_math的行时,res代表的是行数据,里面没有名为'file'的列,自然会抛出找不到键的错误。

方案一:跳过pivot_table,直接在原DataFrame上实现需求

其实你的需求不需要先做透视表,直接在原始数据上处理会更简单高效:

  1. 先给每行标记是否为当前重考记录
  2. 按学生(结合班级、科目确保维度准确)分组,判断该学生是否存在过重考记录

代码示例:

import pandas as pd
df = pd.DataFrame(columns=['file', 'class', 'student', 'subject', 'scores'], 
                  data=[['re_test', 'A', 'John', 'Math', 60], 
                        ['first_test', 'A', 'Scott', 'Math', 75], 
                        ['first_test', 'A', 'Mary', 'Math', 80], 
                        ['re_test', 'B', 'Jack', 'Math', 70], 
                        ['first_test', 'B', 'Mina', 'Math', 75], 
                        ['first_test', 'B', 'James', 'Math', 95]])

# 给每行标记是否为单次重考记录
df['is_re_test'] = df['file'].str.contains('re')

# 按分组维度判断学生是否有过重考历史,同步到每一行
df['Re-test'] = df.groupby(['class', 'student', 'subject'])['is_re_test'].transform('any').map({True: 'Yes', False: 'No'})

print(df)

运行后会给原始数据的每一行都正确标记该学生是否有过重考记录,完全匹配你的需求。

方案二:如果一定要保留pivot_table的使用

如果你坚持要用透视表的方式,需要从多层索引中提取file的值——此时file是索引的一部分,可以通过res.name获取索引元组(你的索引顺序是['class', 'student', 'file'],元组的第三个元素就是file的值):

修改你的代码如下:

df_math= df.pivot_table(index= ['class', 'student', 'file'], values=['subject'], aggfunc=['count'], fill_value = 0)

def retest_check(res):
    # 从索引元组中提取file字段的值
    file_value = res.name[2]
    return 'Yes' if 're' in file_value else 'No'

df_math['Re-test'] = df_math.apply(retest_check, axis=1)

print(df_math)

这样就能正确获取到file的值,避免KeyError的出现。

补充说明

对比两种方案,第一种更贴合你的需求场景:它保留了原始数据的所有行信息,同时给每个学生的每一条记录都标记了重考状态;而第二种透视表的方式会聚合数据,可能丢失原始行的细节。更推荐使用第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:52:48