pandas群体在小组内sorting

我想将我的数据框分成两列,然后对组内的聚合结果进行sorting。

In [167]: df Out[167]: count job source 0 2 sales A 1 4 sales B 2 6 sales C 3 3 sales D 4 7 sales E 5 5 market A 6 3 market B 7 2 market C 8 4 market D 9 1 market E In [168]: df.groupby(['job','source']).agg({'count':sum}) Out[168]: count job source market A 5 B 3 C 2 D 4 E 1 sales A 2 B 4 C 6 D 3 E 7 

现在我想按每个组中的降序对count列进行sorting。 然后只取前三排。 得到像这样的东西:

  count job source market A 5 D 4 B 3 sales E 7 C 6 B 4 

你想要做的,实际上又是一个groupby(根据第一个groupby的结果):按照每个组sorting和取前三个元素。

从第一组的结果开始:

 In [60]: df_agg = df.groupby(['job','source']).agg({'count':sum}) 

我们按指数的第一级进行分组:

 In [63]: g = df_agg['count'].groupby(level=0, group_keys=False) 

然后,我们要对每个组进行sorting(“sorting”),并采取前三个要素:

 In [64]: res = g.apply(lambda x: x.order(ascending=False).head(3)) 

但是,为此,有一个快捷function来做到这一点, nlargest

 In [65]: g.nlargest(3) Out[65]: job source market A 5 D 4 B 3 sales E 7 C 6 B 4 dtype: int64 

你也可以一口气做,先做sorting,然后用头去取每个组的前3个。

 In[34]: df.sort_values(['job','count'],ascending=False).groupby('job').head(3) Out[35]: count job source 4 7 sales E 2 6 sales C 1 4 sales B 5 5 market A 8 4 market D 6 3 market B 

以下是按sorting顺序排列前3的其他示例,并在组内进行sorting:

 In [43]: import pandas as pd In [44]: df = pd.DataFrame({"name":["Foo", "Foo", "Baar", "Foo", "Baar", "Foo", "Baar", "Baar"], "count_1":[5,10,12,15,20,25,30,35], "count_2" :[100,150,100,25,250,300,400,500]}) In [45]: df Out[45]: count_1 count_2 name 0 5 100 Foo 1 10 150 Foo 2 12 100 Baar 3 15 25 Foo 4 20 250 Baar 5 25 300 Foo 6 30 400 Baar 7 35 500 Baar ### Top 3 on sorted order: In [46]: df.groupby(["name"])["count_1"].nlargest(3) Out[46]: name Baar 7 35 6 30 4 20 Foo 5 25 3 15 1 10 dtype: int64 ### Sorting within groups based on column "count_1": In [48]: df.groupby(["name"]).apply(lambda x: x.sort_values(["count_1"], ascending = False)).reset_index(drop=True) Out[48]: count_1 count_2 name 0 35 500 Baar 1 30 400 Baar 2 20 250 Baar 3 12 100 Baar 4 25 300 Foo 5 15 25 Foo 6 10 150 Foo 7 5 100 Foo 

如果你不需要总结一列,那就用@ tvashtar的答案。 如果你需要总结,那么你可以使用@joris的答案或这是非常相似的答案。

 df.groupby(['job']).apply(lambda x: (x.groupby('source') .sum() .sort_values('count', ascending=False)) .head(3))