首页 > 解决方案 > 在已分组的数据框中对每组的值进行排序

问题描述

执行操作时对每个组进行排序有很多答案,groupby但是在我的情况下,我 groupby 然后使用聚合列来创建另一列。我想按每组新创建的列进行排序。

MRE:

df = pd.DataFrame({"A":[1,1,1,3,3,3, 1,1,1,3,3,3],
                   "B":["a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c"],
                   "click":[100, 200, 123, 333, 222, 333, 100, 200, 123, 333, 222, 333],
                   "exp":[10000, 10000, 10000, 10000, 10000, 10000, 20000, 20000, 20000, 20000, 20000, 20000]})

grp_df = df.groupby(["A", "B"]).sum()
grp_df["ctr"] = grp_df["click"] / grp_df["exp"] * 100

输出:

        click   exp     ctr
A   B           
1   a   200     30000   0.666667
    b   400     30000   1.333333
    c   246     30000   0.820000
3   a   666     30000   2.220000
    b   444     30000   1.480000
    c   666     30000   2.220000

期望的输出:

        click   exp     ctr
A   B           
1   b   400     30000   1.333333
    c   246     30000   0.820000
    a   200     30000   0.666667
3   a   666     30000   2.220000
    c   666     30000   2.220000
    b   444     30000   1.480000

标签: pandaspandas-groupby

解决方案


您可以分组A(级别 = 0),然后sort_valuesctr列:

grp_df.groupby(level=0).apply(
  lambda g: g.sort_values('ctr', ascending=False)
).reset_index(level=0, drop=True)

     click    exp       ctr
A B                        
1 b    400  30000  1.333333
  c    246  30000  0.820000
  a    200  30000  0.666667
3 a    666  30000  2.220000
  c    666  30000  2.220000
  b    444  30000  1.480000

或者正如@haneulkim 评论的那样,更简洁的选择是group_keys=False

grp_df.groupby(level=0, group_keys=False).apply(
  lambda g: g.sort_values('ctr', ascending=False))

推荐阅读