如何将列表中的随机值分配给同一行的另一列中不存在的新列?

2024-06-16 14:39:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个大约50k行的数据集,其中包含某个作业ID和执行该作业的人员的用户ID。它由我创建的示例表示:

df = pd.DataFrame(data={
    'job_id': ['00001', '00002', '00003', '00004', '00005', '00006', '00007', '00008', '00009', '00010', '00011', '00012', '00013', '00014', '00015'],
    'user_id': ['frank', 'josh', 'frank', 'jessica', 'josh', 'eric', 'frank', 'josh', 'eric', 'jessica', 'jessica', 'james', 'frank', 'josh', 'james']
})


    job_id  user_id
0   00001   frank
1   00002   josh
2   00003   frank
3   00004   jessica
4   00005   josh
5   00006   eric
6   00007   frank
7   00008   josh
8   00009   eric
9   00010   jessica
10  00011   jessica
11  00012   james
12  00013   frank
13  00014   josh
14  00015   james

我希望在一个名为“reviewer_id”的新列中为这些工作分配同行评论员,其中评论员来自用户id列表,但不能是相同的user_id。例如:frank不能回顾自己的工作,但jessica可以

我想要的输出是这样的:

    job_id  user_id reviewer_id
0   00001   frank   jessica
1   00002   josh    frank
2   00003   frank   josh
3   00004   jessica eric
4   00005   josh    james
...
11  00012   james   frank
12  00013   frank   josh
13  00014   josh    eric
14  00015   james   eric

我对python非常陌生,所以我只能考虑从reviewers = df['user_id'].unique().tolist()获取一个唯一的user_id列表,并在数据帧上迭代并分配一个审阅者ID,但我知道您通常不应该在数据帧上迭代。所以我不知道该怎么做


Tags: 数据frank用户iddf作业joberic
3条回答

我能想到的最简单的方法是不断更换评论者,直到没有人评论他们自己的作品:

users = df['user_id'].unique()
df['reviewer_id'] = df['user_id']
self_review = lambda: df['reviewer_id'] == df['user_id']

while self_review().any():
    reviewers = np.random.choice(users, len(df))
    df['reviewer_id'] = df['reviewer_id'].mask(self_review(), reviewers)

就性能而言,当有更多不同的用户时,代码运行得更快。下面是一个更快的版本(对于walrus:=操作符需要Python 3.8):

users = df['user_id'].unique()
df['reviewer_id'] = df['user_id']

while (self_review := df['user_id'] == df['reviewer_id']).any():
    reviewers = np.random.choice(users, self_review.sum())
    df.loc[self_review, 'reviewer_id'] = reviewers

您可以使用pandasapply根据用户的值检查两个随机审阅者选择,然后返回第一个不是用户的审阅者

import pandas as pd
from random import sample

personnel = df.user_id.unique().tolist()
def random_reviewer(x):
    reviewers = sample(personnel,2)
    if reviewers[0] == x['user_id']:
        return reviewers[1]
    return reviewers[0]
df['reviewer_id'] = df.apply(random_reviewer,axis=1)

您可以将applyset一起使用:

import random
unique_ids = set(df.user_id.unique())
assign = lambda x: random.choice(list(unique_ids - {x}))

df['reviewer_id'] = df.user_id.apply(assign)
print(df)

输出:

   job_id  user_id reviewer_id
0   00001    frank        eric
1   00002     josh        eric
2   00003    frank     jessica
3   00004  jessica       frank
4   00005     josh        eric
5   00006     eric     jessica
6   00007    frank        josh
7   00008     josh       frank
8   00009     eric       james
9   00010  jessica        eric
10  00011  jessica       frank
11  00012    james        josh
12  00013    frank     jessica
13  00014     josh     jessica
14  00015    james        eric

相关问题 更多 >