[英]pandas groupby, then sort within groups
I want to group my dataframe by two columns and then sort the aggregated results within those groups.我想将我的数据框按两列分组,然后对这些组中的聚合结果进行排序。
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
I would now like to sort the 'count' column in descending order within each of the groups, and then take only the top three rows.我现在想在每个组中按降序对“计数”列进行排序,然后只取前三行。 To get something like:
得到类似的东西:
count
job source
market A 5
D 4
B 3
sales E 7
C 6
B 4
You could also just do it in one go, by doing the sort first and using head to take the first 3 of each group.您也可以一次性完成,首先进行排序并使用 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
What you want to do is actually again a groupby (on the result of the first groupby): sort and take the first three elements per group.你想要做的实际上又是一个 groupby (在第一个 groupby 的结果上):对每组的前三个元素进行排序和取。
Starting from the result of the first groupby:从第一个 groupby 的结果开始:
In [60]: df_agg = df.groupby(['job','source']).agg({'count':sum})
We group by the first level of the index:我们按索引的第一级分组:
In [63]: g = df_agg['count'].groupby('job', group_keys=False)
Then we want to sort ('order') each group and take the first three elements:然后我们要对每个组进行排序('order')并取前三个元素:
In [64]: res = g.apply(lambda x: x.sort_values(ascending=False).head(3))
However, for this, there is a shortcut function to do this, nlargest
:但是,为此,有一个快捷功能可以做到这一点,
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
So in one go, this looks like:所以一口气,这看起来像:
df_agg['count'].groupby('job', group_keys=False).nlargest(3)
Here's other example of taking top 3 on sorted order, and sorting within the groups:这是另一个按排序顺序排在前 3 位并在组内排序的示例:
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
试试这个 取而代之,这是一种简单的 groupby 和降序排序的方法:
df.groupby(['companyName'])['overallRating'].sum().sort_values(ascending=False).head(20)
If you don't need to sum a column, then use @tvashtar's answer.如果您不需要对列求和,请使用@tvashtar 的答案。 If you do need to sum, then you can use @joris' answer or this one which is very similar to it.
如果您确实需要求和,那么您可以使用@joris 的答案或与它非常相似的答案。
df.groupby(['job']).apply(lambda x: (x.groupby('source')
.sum()
.sort_values('count', ascending=False))
.head(3))
I was getting this error without using "by":我在不使用“by”的情况下收到此错误:
TypeError: sort_values() missing 1 required positional argument: 'by'类型错误:sort_values() 缺少 1 个必需的位置参数:'by'
So, I changed it to this and now it's working:所以,我把它改成了这个,现在它可以工作了:
df.groupby(['job','source']).agg({'count':sum}).sort_values(by='count',ascending=False).head(20)
You can do it in one line -您可以在一行中完成 -
df.groupby(['job']).apply(lambda x: x.sort_values(['count'], ascending=False).head(3)
.drop('job', axis=1))
what apply() does is that it takes each group of groupby and assigns it to the x in lambda function. apply() 所做的是它获取每组 groupby 并将其分配给 lambda 函数中的 x 。
@joris answer helped a lot. @joris 的回答很有帮助。 This is what worked for me.
这对我有用。
df.groupby(['job'])['count'].nlargest(3)
When grouped dataframe contains more than one grouped column ("multi-index"), using other methods erases other columns:当分组数据框包含多个分组列(“多索引”)时,使用其他方法会擦除其他列:
edf = pd.DataFrame({"job":["sales", "sales", "sales", "sales", "sales",
"market", "market", "market", "market", "market"],
"source":["A", "B", "C", "D", "E", "A", "B", "C", "D", "E"],
"count":[2, 4,6,3,7,5,3,2,4,1],
"other_col":[1,2,3,4,56,6,3,4,6,11]})
gdf = edf.groupby(["job", "source"]).agg({"count":sum, "other_col":np.mean})
gdf.groupby(level=0, group_keys=False).apply(lambda g:g.sort_values("count", ascending=False))
This keeps other_col
as well as ordering by count
column within each group这保持
other_col
以及按每个组内的count
列排序
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.