Присваивание значения группе groupby pandas

Рейтинг: 0Ответов: 2Опубликовано: 13.07.2023

Есть дата фрейм вида:

df = pd.DataFrame({'ID': [111, 222, 333, 333, 444, 555, 555], 'Номер': ['1', '2','3', '4', '5', '6', '7']})

Требуется присвоить случайный номер между 1 и 3 всем ID, но с условием - если ID одинаковый, им присваивается одинаковый номер.

Основная цель - сгруппировать все ID под определенный набор групп, причем, одинаковые ID должны быть под одним номером, а количество групп генерируется случайным образом в диапазоне между заданными числами. Разные группы могут быть под одним номером.

Пробовал через группировку - не сработало:

for group in df['Номер'].groupby(df['ID']):
        df['Номер'] = np.random.randint(1, 4, size=len(df))

Каким образом поместить одинаковые ID под один номер, который генерируется случайным образом?

Ответы

▲ 1Принят

Если работать с объектом группировки в groupby через отдельную функцию с group, работает:

    def assign_random_number(group):
        group['Номер'] = np.random.randint(1, 4)
        return group

    df['Номер'] = df.groupby('ID',group_keys=False).apply(assign_random_number)['Номер']

Получаем требуемый результат:

 ID   Номер
111      1
222      3
333      2
333      2
444      3
444      3
555      1
555      1
▲ 2

Самое простое решение - просвоить id на основании номера группы метода groupby:

df["group_id"] = df.groupby("ID").ngroup()

df:

    ID Номер  group_id
0  111     1         0
1  222     2         1
2  333     3         2
3  333     4         2
4  444     5         3
5  555     6         4
6  555     7         4

Другое дело, как вы 5ти группам будете присваивать три уникальных id - это вопрос тот еще...

UPDATE

Если id могут повторяться, то сделать можно так:

df["group_id"] = df.groupby("ID").transform(lambda x: np.random.randint(1, 4, len(x)))

df:

    ID Номер  group_id
0  111     1         3
1  222     2         1
2  333     3         1
3  333     4         1
4  444     5         1
5  555     6         2
6  555     7         2