Python pandas:保留具有最高列值的行

And*_*Ito 6 python pandas

假设我有一个学生考试成绩的数据框,每个学生学习不同的科目。每个学生可以多次参加每个科目的考试,只保留最高分(满分 100 分)。例如,假设我有一个包含所有测试记录的数据框:

| student_name | subject | test_number | score | 
|--------------|---------|-------------|-------|
| sarah        | maths   | test1       | 78    |
| sarah        | maths   | test2       | 71    |
| sarah        | maths   | test3       | 83    |
| sarah        | physics | test1       | 91    |
| sarah        | physics | test2       | 97    |
| sarah        | history | test1       | 83    |
| sarah        | history | test2       | 87    |
| joan         | maths   | test1       | 83    |
| joan         | maths   | test2       | 88    |
Run Code Online (Sandbox Code Playgroud)

(1) 如何只保留分数最高的测试记录(行)?那是,

| student_name | subject | test_number | score | 
|--------------|---------|-------------|-------|
| sarah        | maths   | test1       | 78    |
| sarah        | maths   | test2       | 71    |
| sarah        | maths   | test3       | 83    |
| sarah        | physics | test1       | 91    |
Run Code Online (Sandbox Code Playgroud)

(2) 我如何保持同一科目、同一学生的所有考试的平均值?那是:

| student_name | subject | test_number | ave_score | 
|--------------|---------|-------------|-----------|
| sarah        | maths   | na          | 77.333    |
| sarah        | maths   | na          | 94        |
| sarah        | maths   | na          | 85        |
| sarah        | physics | na          | 85.5      |
Run Code Online (Sandbox Code Playgroud)

我尝试了df.sort_values()和 的各种组合df.drop_duplicates(subset=..., keep=...),但无济于事。

实际数据

| query | target   | pct-similarity | p-val | aln_length | bit-score |
|-------|----------|----------------|-------|------------|-----------|
| EV239 | B/Fw6/623 | 99.23         | 0.966 |  832       | 356       |
| EV239 | B/Fw6/623 | 97.34         | 0.982 |  1022      | 739       |
| EV239 | MMS-alpha | 92.23         | 0.997 |  838       | 384       |
| EV239 | MMS-alpha | 93.49         | 0.993 |  1402      | 829       |
| EV380 | B/Fw6/623 | 94.32         | 0.951 |  324       | 423       |
| EV380 | B/Fw6/623 | 95.27         | 0.932 |  1245      | 938       |
| EV380 | MMS-alpha | 99.23         | 0.927 |  723       | 522       |
| EV380 | MMS-alpha | 99.15         | 0.903 |  948       | 1092      |
Run Code Online (Sandbox Code Playgroud)

应用聚合函数后,只对列pct-similarity感兴趣。

(1) 通过选择最大值删除重复的查询+目标行aln_length。保留pct-similarity属于最大值的行的值aln_length。

(2) 通过选择具有最大值的行aln_length并计算该pct-similarity组重复行的平均值来聚合重复查询+目标行。其他数字列不是必需的,最终会被删除,所以我真的不在乎对它们应用了什么聚合函数(最大值或平均值)。

raf*_*elc 5

只需用于max()每组学生/科目:

df.groupby(["student_name","subject"], as_index=False).max()


    student_name    subject         test_number     score
0   joan            maths           test2           88
1   sarah           history         test2           87
2   sarah           maths           test3           83
3   sarah           physics         test2           97
Run Code Online (Sandbox Code Playgroud)

对于平均值,可以使用mean():

df.groupby(["student_name","subject"], as_index=False).mean()

    student_name    subject     score
0   joan            maths       85.500000
1   sarah           history     85.000000
2   sarah           maths       77.333333
3   sarah           physics     94.000000
Run Code Online (Sandbox Code Playgroud)


WeN*_*Ben 4

最有describe可能可以

df.groupby(["student_name","subject"]).score.describe()
Out[15]: 
                          count       mean       std   min    25%   50%  \
student_name   subject                                                    
 joan           maths       2.0  85.500000  3.535534  83.0  84.25  85.5   
 sarah          history     2.0  85.000000  2.828427  83.0  84.00  85.0   
                maths       3.0  77.333333  6.027714  71.0  74.50  78.0   
                physics     2.0  94.000000  4.242641  91.0  92.50  94.0   
                            75%   max  
student_name   subject                 
 joan           maths     86.75  88.0  
 sarah          history   86.00  87.0  
                maths     80.50  83.0  
                physics   95.50  97.0  
Run Code Online (Sandbox Code Playgroud)

与drop_duplicates

df.sort_values('score').drop_duplicates(["student_name","subject"],keep='last')
Out[22]: 
     student_name    subject    test_number  score
2   sarah           maths      test3            83
6   sarah           history    test2            87
8   joan            maths      test2            88
4   sarah           physics    test2            97
Run Code Online (Sandbox Code Playgroud)

对于mean价值reindex

df.groupby(["student_name","subject"], as_index=False).mean().reindex(columns=df.columns)
Out[24]: 
     student_name    subject  test_number      score
0   joan            maths             NaN  85.500000
1   sarah           history           NaN  85.000000
2   sarah           maths             NaN  77.333333
3   sarah           physics           NaN  94.000000
Run Code Online (Sandbox Code Playgroud)