比较多行中的学生 ID 并获得所需的输出

Compare Student ID in multiple row and get the desired output

我有一个这样的数据框

Student ID Subject Current class assessment class prev cls current cls next cls
101 English Class 2 Class 2 -- Class2 Pass --
101 English Class2 Class3 -- -- Class3 Pass
101 Mathematics Class 2 Class 2 -- Class 2 fail --
101 Mathematics Class 2 Class 1 Class 1 fail -- --
102 English Class 2 Class 2 -- Class2 Pass --
102 English Class 2 Class 3 -- -- Class 3 Fail
102 Mathematics Class2 Class2 -- Class2 fail --
102 Mathematics Class2 Class1 Class1 Pass -- --

我想要这样的输出

Student ID Subject Current class Expert lvl
101 English Class2 class3 pass
101 Mathematics Class 2 class 1 fail
102 English Class2 class2 pass
102 Mathematics Class 2 class 1 pass

条件是属于class-2的学生参加class-2

的测验

如何在python中写入得到这种数据框?

第一步是将所有 cls 分组到一个列中(不确定是否有多个 cls 列可以与 -- 不同,但这将在此处处理)并按 Student ID 分组和 Subject:

df['cls'] = df[['prev cls', 'current cls', 'next cls']].agg(lambda x: [i for i in x if i!='--'], axis=1)
df = df.groupby(['Student ID', 'Subject'], as_index=False).agg({'Current class': 'last', 'cls': 'sum'})

这给你 df:

   Student ID      Subject Current class                           cls
0         101      English        Class2    [Class2 Pass, Class3 Pass]
1         101  Mathematics       Class 2  [Class 2 fail, Class 1 fail]
2         102      English       Class 2   [Class2 Pass, Class 3 Fail]
3         102  Mathematics        Class2    [Class2 fail, Class1 Pass]

从那里您可以使用一个函数转换 cls 列,该函数将获得最大通过级别或最低失败级别:

import re
def get_expert_lvl(tests: list):
    passed = [x for x in tests if 'pass' in x.lower()]
    if passed:
        return max(passed, key=lambda x: int(re.search(r'\d+', x).group()))
    else:
        return min(tests, key=lambda x: int(re.search(r'\d+', x).group()))

df['Expert lvl'] = df['cls'].transform(get_expert_lvl)
df.drop('cls', axis=1, inplace=True)

你最终得到:

   Student ID      Subject Current class    Expert lvl
0         101      English        Class2   Class3 Pass
1         101  Mathematics       Class 2  Class 1 fail
2         102      English       Class 2   Class2 Pass
3         102  Mathematics        Class2   Class1 Pass