панды groupby сортировка внутри групп
Я хочу сгруппировать свой фрейм данных по двум столбцам, а затем отсортировать агрегированные результаты внутри групп.
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
4 ответов:
то, что вы хотите сделать, на самом деле снова groupby (по результату первого groupby): сортировать и принимать первые три элемента в группе.
начиная с результата первой groupby:
In [60]: df_agg = df.groupby(['job','source']).agg({'count':sum})мы группируем по первому уровню индекса:
In [63]: g = df_agg['count'].groupby(level=0, group_keys=False)затем мы хотим отсортировать ('заказать') каждую группу и взять первые три элемента:
In [64]: res = g.apply(lambda x: x.order(ascending=False).head(3))однако для этого есть функция быстрого доступа, чтобы сделать это,
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
вы также можете просто сделать это за один раз, выполнив сортировку первым и используя 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
вот еще один пример взятия топ-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
Если вам не нужно суммировать столбец, то используйте ответ @tvashtar. Если вам нужно суммировать, то вы можете использовать ответ @joris или этот, который очень похож на него.
df.groupby(['job']).apply(lambda x: (x.groupby('source') .sum() .sort_values('count', ascending=False)) .head(3))
Comments