首页 文章

Python:使用groupby获取具有最大值的行

提问于
浏览
112

我希望我能为我的问题找到帮助 . 我正在寻找以下问题的解决方案:

我有一个dataFrame,如:

Sp  Mt Value  count
0  MM1  S1   a      **3**
1  MM1  S1   n      2
2  MM1  S3   cb     5
3  MM2  S3   mk      **8**
4  MM2  S4   bg     **10**
5  MM2  S4   dgd      1
6  MM4  S2  rd     2
7  MM4  S2   cb      2
8  MM4  S2   uyi      **7**

我的目标是获取组之间计数最大的结果行,例如:

0  MM1  S1   a      **3**
1 3  MM2  S3   mk      **8**
4  MM2  S4   bg     **10** 
8  MM4  S2   uyi      **7**

有人知道我怎么能在熊猫或python中做到这一点?

UPDATE

我没有提供更多关于我的问题的细节 . 对于我的问题,我想按['Sp','Mt'分组 . 让我们举个第二个例子:

Sp   Mt   Value  count
4  MM2  S4   bg     10
5  MM2  S4   dgd    1
6  MM4  S2   rd     2
7  MM4  S2   cb     8
8  MM4  S2   uyi    8

对于上面的例子,我想得到每个组中count等于max的所有行,例如:

MM2  S4   bg     10
MM4  S2   cb     8
MM4  S2   uyi    8

7 回答

  • 25

    简单的解决方案是应用: idxmax() function to get indices of rows with max values. 这将过滤掉组中具有最大值的所有行 .

    In [365]: import pandas as pd
    
    In [366]: df = pd.DataFrame({
    'sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4','MM4'],
    'mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
    'val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
    'count' : [3,2,5,8,10,1,2,2,7]
    })
    
    In [367]: df                                                                                                       
    Out[367]: 
       count  mt   sp  val
    0      3  S1  MM1    a
    1      2  S1  MM1    n
    2      5  S3  MM1   cb
    3      8  S3  MM2   mk
    4     10  S4  MM2   bg
    5      1  S4  MM2  dgb
    6      2  S2  MM4   rd
    7      2  S2  MM4   cb
    8      7  S2  MM4  uyi
    
    
    ### Apply idxmax() and use .loc() on dataframe to filter the rows with max values:
    In [368]: df.loc[df.groupby(["sp", "mt"])["count"].idxmax()]                                                       
    Out[368]: 
       count  mt   sp  val
    0      3  S1  MM1    a
    2      5  S3  MM1   cb
    3      8  S3  MM2   mk
    4     10  S4  MM2   bg
    8      7  S2  MM4  uyi
    
    ### Just to show what values are returned by .idxmax() above:
    In [369]: df.groupby(["sp", "mt"])["count"].idxmax().values                                                        
    Out[369]: array([0, 2, 3, 4, 8])
    
  • 8

    您可以按计数对dataFrame进行排序,然后删除重复项 . 我认为这更容易:

    df.sort_values('count', ascending=False).drop_duplicates(['Sp','Mt'])
    
  • 3

    对我来说,最简单的解决方案是在count等于最大值时保持值 . 因此,以下一行命令就足够了:

    df[df['count'] == df.groupby(['Mt'])['count'].transform(max)]
    
  • 1
    In [1]: df
    Out[1]:
        Sp  Mt Value  count
    0  MM1  S1     a      3
    1  MM1  S1     n      2
    2  MM1  S3    cb      5
    3  MM2  S3    mk      8
    4  MM2  S4    bg     10
    5  MM2  S4   dgd      1
    6  MM4  S2    rd      2
    7  MM4  S2    cb      2
    8  MM4  S2   uyi      7
    
    In [2]: df.groupby(['Mt'], sort=False)['count'].max()
    Out[2]:
    Mt
    S1     3
    S3     8
    S4    10
    S2     7
    Name: count
    

    要获得原始DF的索引,您可以执行以下操作:

    In [3]: idx = df.groupby(['Mt'])['count'].transform(max) == df['count']
    
    In [4]: df[idx]
    Out[4]:
        Sp  Mt Value  count
    0  MM1  S1     a      3
    3  MM2  S3    mk      8
    4  MM2  S4    bg     10
    8  MM4  S2   uyi      7
    

    请注意,如果每个组有多个最大值,则将返回所有值 .

    Update

    关于这是OP要求的冰雹机会:

    In [5]: df['count_max'] = df.groupby(['Mt'])['count'].transform(max)
    
    In [6]: df
    Out[6]:
        Sp  Mt Value  count  count_max
    0  MM1  S1     a      3          3
    1  MM1  S1     n      2          3
    2  MM1  S3    cb      5          8
    3  MM2  S3    mk      8          8
    4  MM2  S4    bg     10         10
    5  MM2  S4   dgd      1         10
    6  MM4  S2    rd      2          7
    7  MM4  S2    cb      2          7
    8  MM4  S2   uyi      7          7
    
  • 27

    尝试了Zelazny在一个相对较大的DataFrame(约400k行)上建议的解决方案后,我发现它非常慢 . 我发现这是一种替代方案,可以在我的数据集上更快地运行数量级 .

    df = pd.DataFrame({
        'sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4', 'MM4'],
        'mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
        'val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
        'count' : [3,2,5,8,10,1,2,2,7]
        })
    
    df_grouped = df.groupby(['sp', 'mt']).agg({'count':'max'})
    
    df_grouped = df_grouped.reset_index()
    
    df_grouped = df_grouped.rename(columns={'count':'count_max'})
    
    df = pd.merge(df, df_grouped, how='left', on=['sp', 'mt'])
    
    df = df[df['count'] == df['count_max']]
    
  • 88
    df = pd.DataFrame({
    'sp' : ['MM1', 'MM1', 'MM1', 'MM2', 'MM2', 'MM2', 'MM4', 'MM4','MM4'],
    'mt' : ['S1', 'S1', 'S3', 'S3', 'S4', 'S4', 'S2', 'S2', 'S2'],
    'val' : ['a', 'n', 'cb', 'mk', 'bg', 'dgb', 'rd', 'cb', 'uyi'],
    'count' : [3,2,5,8,10,1,2,2,7]
    })
    
    df.groupby(['sp', 'mt']).apply(lambda grp: grp.nlargest(1, 'count'))
    
  • 174

    使用 groupbyidxmax 方法:

    • 将col date 转移到 datetime
    df['date']=pd.to_datetime(df['date'])
    

    groupyby ad_id 之后

    • 获取列 datemax 的索引:
    idx=df.groupby(by='ad_id')['date'].idxmax()
    
    • 获取所需数据:
    df_max=df.loc[idx,]
    

    出[54]:

    ad_id  price       date
    7     22      2 2018-06-11
    6     23      2 2018-06-22
    2     24      2 2018-06-30
    3     28      5 2018-06-22
    

相关问题