如何用pandas按学生、版本分组统计及格不及格人数等多字段
实现方案
方案1:单步groupby聚合(更高效,推荐)
直接通过一次分组聚合完成所有指标计算,无需单独做透视表再拼接:
res_df = master_df.groupby( ['student', 'version', 'status'], as_index=False ).agg( # 统计通过数量 pass_count=('result', lambda x: (x == 'pass').sum()), # 统计未通过数量 fail_count=('result', lambda x: (x == 'fail').sum()), # 统计组内总记录数 total_count=('result', 'size'), # 拼接所有不及格科目,自动过滤空值 merged_failed_subject=('Failed Subject', lambda x: ', '.join(sub for sub in x if pd.notna(sub))) )
方案2:兼容原有pivot_table逻辑
如果你需要保留已有的透视表逻辑,可以单独聚合不及格科目后和透视表结果合并:
# 原有透视表逻辑,处理多索引列名 pivot_df = pd.pivot_table( master_df, index=['status', 'student', 'version'], columns=['result'], aggfunc=len, fill_value=0 ).reset_index() # 重命名列,去除层级 pivot_df.columns = ['status', 'student', 'version', 'fail_count', 'pass_count'] # 计算总记录数 pivot_df['total_count'] = pivot_df['fail_count'] + pivot_df['pass_count'] # 单独聚合不及格科目 failed_sub_df = master_df.groupby( ['status', 'student', 'version'], as_index=False )['Failed Subject'].agg( merged_failed_subject = lambda x: ', '.join(sub for sub in x if pd.notna(sub)) ) # 合并两个结果得到最终表 res_df = pd.merge(pivot_df, failed_sub_df, on=['status', 'student', 'version'], how='left')
注意事项
- 拼接不及格科目时加入了
pd.notna判断,避免空值被转为字符串nan混入结果 - 如果分组内没有不及格科目,
merged_failed_subject会返回空字符串,可根据需求替换为None或其他默认占位符 - 可通过调整
groupby参数内的字段顺序,调整输出结果的分组排序规则
内容的提问来源于stack exchange,提问作者naina
相关产品推荐
相关产品推荐

