【问题标题】:filter for rows with n largest values for each group过滤每组具有 n 个最大值的行
【发布时间】:2020-06-02 17:14:20
【问题描述】:

上下文

对于每支球队,我想要包含前三名得分球员的数据框行。

在我的脑海中,它是Dataframe.nlargest()Dataframe.groupby() 的组合,但我不认为这是受支持的。 我理想的解决方案是:

  • 直接在df 上执行,无需创建其他数据帧
  • 清晰,并且
  • 相对性能好(真正的 df 形状是 7M 行和 5 列)

输入

import pandas as pd
df = pd.read_json('{"team":{"0":"A","1":"A","2":"A","3":"A","4":"A","5":"B","6":"B","7":"B","8":"B","9":"B","10":"C","11":"C","12":"C","13":"C","14":"C"},"player":{"0":"Alice","1":"Becky","2":"Carmen","3":"Donna","4":"Elizabeth","5":"Fran","6":"Greta","7":"Heather","8":"Iris","9":"Jackie","10":"Kelly","11":"Lucy","12":"Molly","13":"Nina","14":"Ophelia"},"points":{"0":15,"1":11,"2":13,"3":8,"4":10,"5":28,"6":29,"7":18,"8":25,"9":9,"10":12,"11":23,"12":18,"13":10,"14":15}}')
| team | player    | points |
|------|-----------|--------|
| A    | Alice     | 15     |
| A    | Becky     | 11     |
| A    | Carmen    | 13     |
| A    | Donna     | 8      |
| A    | Elizabeth | 10     |
| B    | Fran      | 28     |
| B    | Greta     | 29     |
| B    | Heather   | 18     |
| B    | Iris      | 25     |
| B    | Jackie    | 9      |
| C    | Kelly     | 12     |
| C    | Lucy      | 23     |
| C    | Molly     | 18     |
| C    | Nina      | 10     |
| C    | Ophelia   | 15     |

所需的输出

df_output = pd.read_json('{"team":{"0":"A","1":"A","2":"A","3":"B","4":"B","5":"B","6":"C","7":"C","8":"C"},"player":{"0":"Alice","1":"Becky","2":"Carmen","3":"Fran","4":"Greta","5":"Iris","6":"Lucy","7":"Molly","8":"Ophelia"},"points":{"0":15,"1":11,"2":13,"3":28,"4":29,"5":25,"6":23,"7":18,"8":15}}')
df_output
| team | player  | points |
|------|---------|--------|
| A    | Alice   | 15     |
| A    | Becky   | 11     |
| A    | Carmen  | 13     |
| B    | Fran    | 28     |
| B    | Greta   | 29     |
| B    | Iris    | 25     |
| C    | Lucy    | 23     |
| C    | Molly   | 18     |
| C    | Ophelia | 15     |

【问题讨论】:

    标签: python pandas dataframe pandas-groupby


    【解决方案1】:

    您可以将df.groupbydf.nlargest 一起使用

    df.groupby('team').apply(lambda x:x.nlargest(3,'points')).reset_index(drop=True)
    
      team   player  points
    0    A    Alice      15
    1    A   Carmen      13
    2    A    Becky      11
    3    B    Greta      29
    4    B     Fran      28
    5    B     Iris      25
    6    C     Lucy      23
    7    C    Molly      18
    8    C  Ophelia      15
    

    【讨论】:

    • 好的,这就是我要找的。澄清。 groupby-apply lambda 中的x var 是属于特定组的行的子集吗?和type(x)==Dataframe?出于某种原因,我认为x 会是一行...
    • @AndersSwanson 是的,xDataFramefor k,g in df.groupby('team'): print(k) 应该让您了解每个组的 DataFrame。
    【解决方案2】:

    您可以使用df.groupby.rank方法:

    In [1401]: df[df.groupby('team')['points'].rank(ascending=False) <= 3]
    Out[1401]: 
       team   player  points
    0     A    Alice      15
    1     A    Becky      11
    2     A   Carmen      13
    5     B     Fran      28
    6     B    Greta      29
    8     B     Iris      25
    11    C     Lucy      23
    12    C    Molly      18
    14    C  Ophelia      15
    

    【讨论】:

    • 选择这个答案 b/c 比 @Ch3steR 的方法快 7 倍
    【解决方案3】:

    这样的事情可能会奏效 -

    df.loc[df.groupby(['team'])['points'].nlargest(3).reset_index().drop(['team','points'], axis=1)['level_1'].values]
       team   player  points
    0     A    Alice      15
    2     A   Carmen      13
    1     A    Becky      11
    6     B    Greta      29
    5     B     Fran      28
    8     B     Iris      25
    11    C     Lucy      23
    12    C    Molly      18
    14    C  Ophelia      15
    

    【讨论】:

      【解决方案4】:

      另一种方式是sort_valuesgroupby().tail/head

      df.sort_values('points').groupby('team').tail(3)
      

      输出:

         team   player  points
      1     A    Becky      11
      2     A   Carmen      13
      0     A    Alice      15
      14    C  Ophelia      15
      12    C    Molly      18
      11    C     Lucy      23
      8     B     Iris      25
      5     B     Fran      28
      6     B    Greta      29
      

      或者

      df.sort_values('points', ascending=False).groupby('team').head(3)
      

      输出:

         team   player  points
      6     B    Greta      29
      5     B     Fran      28
      8     B     Iris      25
      11    C     Lucy      23
      12    C    Molly      18
      0     A    Alice      15
      14    C  Ophelia      15
      2     A   Carmen      13
      1     A    Becky      11
      

      【讨论】:

        猜你喜欢
        • 2013-08-23
        • 2020-03-27
        • 1970-01-01
        • 2022-06-11
        • 1970-01-01
        • 2015-07-31
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        相关资源
        最近更新 更多