按一列对每个组进行排序,并根据每个组获取顶部元素

Posted

技术标签:

【中文标题】按一列对每个组进行排序,并根据每个组获取顶部元素【英文标题】:Order each group by one column and get top elements depending on each group 【发布时间】:2021-12-28 06:43:58 【问题描述】:

我有一个带有以下列的 pandas 数据框:

month userID probability top_users_that_month
9 A 5.231 3
9 B 0.963 3
9 E 7.445 3
9 D 9.343 3
9 C 3.231 3
10 X 0.963 1
10 B 7.445 1
10 A 2.343 1
13 Y 1.963 2
13 B 9.445 2
13 D 0.343 2

我想创建一个标志列,其值为 1 或 0,具体取决于用户 ID 是否在每个月的 top_users 中(根据他们的probability 列)。请注意,每个月的热门用户数由top_users_that_month 列表示。

所需的输出如下:

month userID probability top_users_that_month flag_among_top_users
9 A 5.231 3 1
9 B 0.963 3 0
9 E 7.445 3 1
9 D 9.343 3 1
9 C 3.231 3 0
10 X 0.963 1 0
10 B 7.445 1 1
10 A 2.343 1 0
11 Y 1.963 2 1
11 B 9.445 2 1
11 D 0.343 2 0

我尝试使用groupbyapply 创建列,但没有得到我想要的结果。

【问题讨论】:

【参考方案1】:
treshold = 5
df['flag_among_top_users'] = (df['probability'] > treshold).astype(int)

输出:

month userID probability top_users_that_month flag_among_top_users
0 9 A 5.231 3 1
1 9 B 0.963 3 0
2 9 E 7.445 3 1
3 9 D 9.343 3 1
4 9 C 3.231 3 0
5 10 X 0.963 1 0
6 10 B 7.445 1 1
7 10 A 2.343 1 0
8 13 Y 1.963 2 0
9 13 B 9.445 2 1
10 13 D 0.343 2 0

【讨论】:

【参考方案2】:

由于每个组要标记的用户数量不同,最简单的方法是使用自定义函数,使用 groupbyapply

例如:

def get_top_users(df):
    top_users = df['top_users_that_month'].iloc[0]
    idx = df.sort_values('probability', ascending=False).head(top_users).index
    df['flag_among_top_users'] = 0
    df.loc[idx, 'flag_among_top_users'] = 1
    return df
    
df.groupby('month').apply(get_top_users)

结果:

    month userID  probability  top_users_that_month  flag_among_top_users
0       9      A        5.231                     3                     1
1       9      B        0.963                     3                     0
2       9      E        7.445                     3                     1
3       9      D        9.343                     3                     1
4       9      C        3.231                     3                     0
5      10      X        0.963                     1                     0
6      10      B        7.445                     1                     1
7      10      A        2.343                     1                     0
8      13      Y        1.963                     2                     1
9      13      B        9.445                     2                     1
10     13      D        0.343                     2                     0

也可以使用nlargest 而不是在get_top_users 内部进行排序,但如果有两个相同的probability 值可能会出现问题。

【讨论】:

非常感谢!这就是我要找的答案! @JavierMonsalve:乐于助人:)

以上是关于按一列对每个组进行排序,并根据每个组获取顶部元素的主要内容,如果未能解决你的问题,请参考以下文章

如何根据另一个列表中元组元素的顺序对元组列表进行排序?

如何将元组列表转换为 pandas 数据框,以便每个元组的第一个值代表一列?

如何使用现有的整数排序对整数元组进行排序?

MySQL - 按一列分组并获得最低值

sql语句 按一列分组 然后再按别一列组内排序?

根据第一列对 CSV 文件进行排序