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

我希望我能为我的问题find帮助。 我正在为以下问题寻找解决scheme:

我有一个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** 

有人知道如何在pandas或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 

对于上面的例子,我想要得到所有的行在哪里计数等于最大在每个组例如:

 MM2 S4 bg 10 MM4 S2 cb 8 MM4 S2 uyi 8 
 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 

请注意,如果每组有多个最大值,则全部将被返回。

更新

这是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 

您可以通过计数对dataFrame进行sorting,然后删除重复项。 我认为这很容易:

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

在一个相对较大的DataFrame(〜400k行)上尝试了Zelaznybuild议的解决scheme后,我发现它非常慢。 这是我发现在我的数据集上运行速度更快的另一种方法。

 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']] 

对于我来说,最简单的解决scheme将保持价值,当计数等于最大值。 因此,下面的一行命令就足够了:

 df[df['count'] == df.groupby(['Mt'])['count'].transform(max)] 

简单的解决办法是应用: idxmax()函数来获取具有最大值的行的索引。 这将过滤出组中具有最大值的所有行。

 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])