如何使用pandas按条件计算每行有效总学分(不及格课程学分不计)
Pandas逐行统计及格课程总学分实现方案
原有代码失效原因
- 语法错误:代码括号未闭合
- 逻辑错误:
isin(['D','E'])返回的是由True/False组成的布尔矩阵,无法直接和数值类型的学分做减法运算,必须先映射为对应要扣除的学分数值才能参与计算。
推荐实现方案
优先用手动列明课程列的写法,避免列顺序错位导致计算错误,逻辑直观易维护:
# 按课程一一对应顺序,分别列好学分列、成绩列 credit_cols = ['s_matdas', 's_fisdas', 's_pentekkin', 's_pemdas', 's_pengpend', 's_pendag', 's_pancasila', 's_bindo'] score_cols = ['n_matdas', 'n_fisdas', 'n_pentekkin', 'n_pemdas', 'n_pengpend', 'n_pendag', 'n_pancasila', 'n_bindo'] # 成绩为D/E的课程学分记0,其余保留原学分,逐行求和得到有效总学分 df_ilkom1['sks'] = df_ilkom1[credit_cols].where( ~df_ilkom1[score_cols].isin(['D', 'E']).values, 0 ).sum(axis=1)
逻辑说明
df_ilkom1[score_cols].isin(['D', 'E'])生成和成绩表维度一致的布尔矩阵,成绩为D/E(不及格)的位置标记为True,及格位置为False,前面加~做取反操作where()方法会保留布尔值为True位置的原学分数值,False位置的学分替换为0- 最后沿行方向调用
sum(axis=1),得到的就是每行排除不及格课程后的有效总学分 - 以给出的第一行样例数据验证:原始总学分21,仅
n_pendag为D对应3学分被记0,最终计算结果为18,符合规则。
等价写法(总学分扣减不及格学分思路)
如果更习惯用「总学分减去不及格课程学分」的思路,可以用下面的代码,注意要把布尔矩阵和对应学分做矩阵乘法,得到需要扣除的总分值:
# 计算所有课程原始总学分 total_credit = df_ilkom1.loc[:, 's_matdas':'s_bindo'].sum(axis=1) # 标记不及格课程位置 fail_flag = df_ilkom1.loc[:, 'n_matdas':'n_bindo'].isin(['D','E']).values # 计算需要扣除的不及格课程总学分 deduct_credit = (df_ilkom1.loc[:, 's_matdas':'s_bindo'].values * fail_flag).sum(axis=1) # 得到有效总学分 df_ilkom1['sks'] = total_credit - deduct_credit
注意事项
- 用列范围切片(
loc[:, '起始列':'结束列'])的时候,必须提前确认DataFrame的列顺序,保证学分列和成绩列的课程顺序完全一一对应,否则会出现课程匹配错位、计算结果错误的问题,手动列明列名的写法容错率更高。 - 如果后续新增其他不及格等级(比如缺考标记F等),直接把对应值加到
isin()的列表里即可。
内容的提问来源于stack exchange,提问作者skywalker56
相关产品推荐
相关产品推荐

