Вопрос в том, чтобы обновить значения столбца уникальными значениями для каждой группы в 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" на основе условия о другом столбце.
Итак, я сначала сделал groupby для match_id. Теперь для каждых 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.
Это то, что я ожидаю получить в качестве результата (обратите внимание на столбец "rank")
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
Любая помощьвысоко ценится.