首页 > 解决方案 > Groupby并用每个组的某个范围内的随机数替换某些值

问题描述

问题是关于根据某些条件为 groupby 中的每个组更新具有唯一值的列的值。

我有一个这样的数据框:

import numpy as np
import pandas as pd

df = pd.DataFrame({'match_id': ['m1', 'm1', 'm1', 'm1', 'm1', 'm1', 'm2', 'm2', 'm2', 'm2', 'm2', 'm2', 'm3', 'm3', 'm3', 'm3'],
                   'name':['peter', 'mike', 'jeff', 'john', 'alex', 'joe', 'jeff', 'peter', 'alex', 'li', 'joe', 'tom', 'mike', 'john', 'tom', 'peter'],
                   'rank': [3, 3, 3, 3, 1, 2, 1, 2, 4, 2, 3, 2, 1, 2, 3, 2],
                  'rating': [1500, 1500, 1500, 1500, 1550, 1540, 1640, 1500, 1390, 1500, 1450, 1500, 1720, 1500, 1320, 1500]})

我需要根据另一列的条件为“match_id”中的每组值修改一些数字。

所以,我首先在 match_id 上做了一个 groupby。现在,对于“评级”列中的每 1500,我想将“等级”列中的相应值更新为 1 到相应组的长度范围内的值,该组在组中也是唯一的。

这是我到目前为止所做的:


new = pd.DataFrame()
grouped = df.groupby('match_id', sort=False)
for name, dfg in grouped:
    dfm = dfg.copy()
    num = len(dfm.loc[dfm['rating'] == 1500])
    dfm.loc[dfm['rating'] == 1500, 'rank'] = np.random.choice(range(1,len(dfm)+1), num, replace=False)
    new = pd.concat([new, dfm], sort = True)

这可行,但有两个问题。首先,以这种方式生成的数字可能已经存在于组中(在其他行上)。我希望生成的随机数是唯一的,这意味着相应组中不存在这些数字。

其次,这对我的原始数据集(125000 个组)来说太长了。所以我需要它比 loc 更高效、更快。

这是我期望得到的输出(注意“等级”列)

    match_id    name    rank    rating
0         m1    peter      6    1500
1         m1    mike       5    1500
2         m1    jeff       4    1500
3         m1    john       3    1500
4         m1    alex       1    1550
5         m1    joe        2    1540
6         m2    jeff       1    1640
7         m2    peter      2    1500
8         m2    alex       4    1390
9         m2    li         5    1500
10        m2    joe        3    1450
11        m2    tom        6    1500
12        m3    mike       1    1720
13        m3    john       4    1500
14        m3    tom        3    1320
15        m3    peter      2    1500

非常感谢任何帮助。

标签: pythonpandasnumpyrandompandas-groupby

解决方案


推荐阅读