8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Pandas Dataframe - 分组、排序和展平(无需聚合)

Curious_learner 1月前

6 0

我有一个运动员数据框,其中包括运动员 ID、团队 ID、姓名和在某项比赛中的得分。每支队伍最多可以有 20 名运动员:当前:运动员 ID 团队 ID 姓名 Sc...

我有一个运动员数据框,其中包括运动员 ID、团队 ID、姓名和某项比赛中的得分。每支队伍最多可有 20 名运动员:

当前的:

AthleteID    TeamID     Name     Score
   1            2        Bob      4.9
   2            1        Pete     4.6
   3            2        Steve    4.5
   4            1        Jim      3.6
   5            3        Frank    4.2

我希望每个队一行,按得分对运动员进行排序,并将他们的信息作为带有排名的列,如下所示:

期望:

     TeamID     AthleteID_1    Name_1   Score_1     AthleteID_2    Name_2   Score_2
       1              2         Pete      4.6          4            Jim      3.6
       2              1         Bob       4.9          3            Steve    4.5  
       3              5         Frank     4.2        None           None     None    

按 T​​eamID 分组后,如何按分数排序并创建这些新列?我目前正在迭代执行此操作,我知道这不是最有效或最 Python 的方式。

帖子版权声明 1、本帖标题:Pandas Dataframe - 分组、排序和展平(无需聚合)
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Curious_learner在本站《pandas》版块原创发布, 转载请注明出处!
最新回复 (0)
  • mrek 1月前 0 只看Ta
    引用 2

    您可以 groupby.rank 然后 pivot :

    out = (df.assign(rank=df.groupby('TeamID')['Score']
                            .rank('dense', ascending=False).astype(int))
             .pivot(index='TeamID', columns='rank')
             .sort_index(level=1, axis=1, sort_remaining=False)
           )
    out.columns = out.columns.map(lambda x: f'{x[0]}_{x[1]}')
    out.reset_index(inplace=True)
    

    输出:

       TeamID  AthleteID_1 Name_1  Score_1  AthleteID_2 Name_2  Score_2
    0       1          2.0   Pete      4.6          4.0    Jim      3.6
    1       2          1.0    Bob      4.9          3.0  Steve      4.5
    2       3          5.0  Frank      4.2          NaN    NaN      NaN
    
  • out = (
        df.assign(
            rank=df.groupby('TeamID')['Score']
            .rank(ascending=False, method='first')
            .astype('int')
            .astype('str')
        )
        .pivot(index='TeamID', columns='rank')
        .pipe(lambda x: x.set_axis(x.columns.map('_'.join), axis=1))
        .sort_index(axis=1, key=lambda x: x.str.split('_').str[1].astype('int'))
        .reset_index()
    )
    

    出去:

       TeamID  AthleteID_1 Name_1  Score_1  AthleteID_2 Name_2  Score_2
    0       1          2.0   Pete      4.6          4.0    Jim      3.6
    1       2          1.0    Bob      4.9          3.0  Steve      4.5
    2       3          5.0  Frank      4.2          NaN    NaN      NaN
    

    示例代码

    import pandas as pd
    data = {'AthleteID': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}, 
            'TeamID': {0: 2, 1: 1, 2: 2, 3: 1, 4: 3}, 
            'Name': {0: 'Bob', 1: 'Pete', 2: 'Steve', 3: 'Jim', 4: 'Frank'}, 
            'Score': {0: 4.9, 1: 4.6, 2: 4.5, 3: 3.6, 4: 4.2}}
    df = pd.DataFrame(data)
    
  • import pandas as pd
    
    data = {'AthleteID': [1, 2, 3, 4, 5],
            'TeamID': [2, 1, 2, 1, 3],
            'Name': ['Bob', 'Pete', 'Steve', 'Jim', 'Frank'],
            'Score': [4.9, 4.6, 4.5, 3.6, 4.2]}
    
    df = pd.DataFrame(data)
    print(df)
    """
       AthleteID  TeamID   Name  Score
    0          1       2    Bob    4.9
    1          2       1   Pete    4.6
    2          3       2  Steve    4.5
    3          4       1    Jim    3.6
    4          5       3  Frank    4.2
    """
    res = (
    df.sort_values(['TeamID','Score'],ascending=[True,False])
    .assign(Rank = lambda d : d.groupby('TeamID').cumcount() +1 )    
    .set_index(['TeamID','Rank']).unstack()
    .sort_index(axis=1,level =1) # to maintain order
    .reset_index()
    )
    print(res)
    """
         TeamID AthleteID   Name Score AthleteID   Name Score
    Rank                1      1     1         2      2     2
    0         1       2.0   Pete   4.6       4.0    Jim   3.6
    1         2       1.0    Bob   4.9       3.0  Steve   4.5
    2         3       5.0  Frank   4.2       NaN    NaN   NaN
    """
    #res.columns = [f'{col[0]}_{col[1]}' if col[0] != 'TeamID' else col[0] for col in res.columns]
    res.columns = res.columns.map(lambda col: f'{col[0]}_{col[1]}' if col[0] != 'TeamID' else col[0] )
    print(res)
    
    """
       TeamID  AthleteID_1 Name_1  Score_1  AthleteID_2 Name_2  Score_2
    0       1          2.0   Pete      4.6          4.0    Jim      3.6
    1       2          1.0    Bob      4.9          3.0  Steve      4.5
    2       3          5.0  Frank      4.2          NaN    NaN      NaN
    """
    
返回
作者最近主题: