如何避免生成列数过多的DataFrame以统计各班级每题答题表现排名
核心解决思路
放弃多列宽表结构,改用按题目+学校+班级为行维度的长表存储统计结果,不会因班级数量增多出现列爆炸问题,后续筛选、排序、查询也更灵活。
实现代码
首先修正你原有代码中列名拼写错误(你原代码里写的scl和实际列名school不匹配),完整实现如下:
import pandas as pd # ---------------------- 数据预处理 ---------------------- # 场景1:仅保留每位学生对应题目的第一次作答 df_first_attempt = df.drop_duplicates( subset=["student", "school", "class", "question"], keep="first" ) # 场景2:全量作答记录直接使用原始df即可 # ---------------------- 按题目统计班级排名函数 ---------------------- def get_question_wise_rank(input_df): # 按 学校+题目+班级 分组计算单题正确率 stat_df = input_df.groupby( ['school', 'question', 'class'] )['answer'].mean().rename('correct_rate').reset_index() # 按题目分组,生成每个题目下的班级排名(正确率降序,同分同名次) stat_df['rank_in_question'] = stat_df.groupby( ['school', 'question'] )['correct_rate'].rank(ascending=False, method='min').astype(int) # 按题目+排名排序,方便查看 stat_df = stat_df.sort_values(['question', 'rank_in_question'], ignore_index=True) return stat_df # ---------------------- 调用得到结果 ---------------------- # 首次作答场景的按题目排名结果 df_first_rank = get_question_wise_rank(df_first_attempt) # 全量作答场景的按题目排名结果 df_all_rank = get_question_wise_rank(df)
输出示例(首次作答场景)
| school | question | class | correct_rate | rank_in_question |
|---|---|---|---|---|
| scl | x | sec | 1.0 | 1 |
| scl | x | first | 0.5 | 2 |
| scl | y | first | 0.0 | 1 |
| scl | y | sec | 0.0 | 1 |
| scl | z | sec | 1.0 | 1 |
| scl | z | third | 1.0 | 1 |
可选操作:按需生成单题宽表
如果临时需要查看某道题的各班表现对比,可以单独筛选后生成宽表,不会出现全量50列的问题:
# 示例:查看x题的各班正确率宽表 df_first_rank[df_first_rank['question'] == 'x'].pivot( index='question', columns='class', values='correct_rate' )
内容的提问来源于stack exchange,提问作者futuredataengineer
相关产品推荐
相关产品推荐

