Python 在组内按组排序
我想按两列对数据帧进行分组,然后在组内对聚合结果进行排序Python 在组内按组排序,python,sorting,pandas,group-by,Python,Sorting,Pandas,Group By,我想按两列对数据帧进行分组,然后在组内对聚合结果进行排序 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
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列进行排序。然后只取最上面的三排。要获得类似于:
count
job source
market A 5
D 4
B 3
sales E 7
C 6
B 4
实际上,您要做的是再次创建一个groupby(基于第一个groupby的结果):排序并获取每个组的前三个元素 从第一个groupby的结果开始:
In [60]: df_agg = df.groupby(['job','source']).agg({'count':sum})
我们按照指数的第一级进行分组:
In [63]: g = df_agg['count'].groupby('job', group_keys=False)
然后我们要对每组进行排序(“顺序”),并取前三个元素:
In [64]: res = g.apply(lambda x: x.sort_values(ascending=False).head(3))
但是,为此,有一个快捷方式函数:
一次完成后,看起来像:
df_agg['count'].groupby('job', group_keys=False).nlargest(3)
你也可以一次完成,先排序,然后用head取每组的前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
下面是关于排序顺序和组内排序的前三名的另一个示例:
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))
试试这个
按降序进行“分组”和排序的简单方法
你可以在一行中完成-
df.groupby(['job']).apply(lambda x: x.sort_values(['count'], ascending=False).head(3)
.drop('job', axis=1))
apply()的作用是将每组groupby赋值给lambda函数中的x。我在没有使用“by”的情况下得到了这个错误: TypeError:sort\u values()缺少1个必需的位置参数:“by” 所以,我把它改成了这个,现在它开始工作了:
df.groupby(['job','source']).agg({'count':sum}).sort_values(by='count',ascending=False).head(20)
@乔里斯的回答帮助很大。 这就是我的工作
df.groupby(['job'])['count'].nlargest(3)
是否有办法将每组前三名结果中未包含的所有内容进行汇总,并将它们添加到每个作业的名为“其他”的源组中?
order
不推荐使用sort\u values
代替感谢您的回答。对于下一步,是否有方法根据groupby列中的值分配排序顺序?例如,如果值为“Buy”,则升序排序;如果值为“Sell”,则降序排序。创建一个正常的数据帧,然后按正常排序可能更容易。@young_souvlaki您仍然需要groupby操作,以便每组只取前3个,这在正常的排序中是不可能的,因为sortDoesgroupby
可以保证订单得到保留?看起来是这样的;from:groupby保留每个grouptoto_tico中的行顺序-这是正确的,但是在解释该语句时需要小心。保留单个组中的行顺序,但是默认情况下groupby有一条sort=True语句,这意味着组本身可能已按键排序。换句话说,如果我的数据帧有键(输入时)3 2 1,。。group by对象将按顺序1 2 3(已排序)显示3个组。使用sort=False确保保留组顺序和行顺序。head(3)给出了3个以上的结果?@Nabin应用于groupby
,它似乎提供了前3个结果 每组的行数。
df.groupby(['job','source']).agg({'count':sum}).sort_values(by='count',ascending=False).head(20)
df.groupby(['job'])['count'].nlargest(3)