Python: случайный выбор для каждой группы

Скажем, что у меня есть кадр данных, который выглядит так:

Name Group_Id
AAA  1
ABC  1
CCC  2
XYZ  2
DEF  3 
YYH  3

Как я мог случайно выбрать одну (или более) строку для каждого Group_Id? Скажем, что мне нужна одна случайная ничья за Group_Id, я бы получил:

Name Group_Id
AAA  1
XYZ  2
DEF  3

Ответ 1

size = 2        # sample size
replace = True  # with replacement
fn = lambda obj: obj.loc[np.random.choice(obj.index, size, replace),:]
df.groupby('Group_Id', as_index=False).apply(fn)

Ответ 2

Начиная с 0.16.x pd.DataFrame.sample предоставляет способ возврата случайной выборки элементов с оси объекта.

In [664]: df.groupby('Group_Id').apply(lambda x: x.sample(1)).reset_index(drop=True)
Out[664]:
  Name  Group_Id
0  ABC         1
1  XYZ         2
2  DEF         3

Ответ 3

Использование groupby и random.choice в элегантном одном слое:

df.groupby('Group_Id').apply(lambda x :x.iloc[random.choice(range(0,len(x)))])

Ответ 4

Есть два способа сделать это очень просто, один без использования чего-либо, кроме основного синтаксиса панд:

df[['x','y']].groupby('x').agg(pd.DataFrame.sample)

Это занимает 14,4 мс с набором данных 50k строк.

Другой, немного более быстрый метод, включает в себя numpy.

df[['x','y']].groupby('x').agg(np.random.choice)

Это займет 10,9 мс с (таким же) набором данных из 50 тыс. Строк.

Вообще говоря, при использовании панд предпочтительно придерживаться собственного синтаксиса. Особенно для начинающих.

Ответ 5

для случайного выбора только одной строки на группу попробуйте df.sample(frac = 1.0).groupby('Group_Id').head(1)

Ответ 6

Используя random.choice, вы можете сделать что-то вроде этого:

import random
name_group = {'AAA': 1, 'ABC':1, 'CCC':2, 'XYZ':2, 'DEF':3, 'YYH':3}

names = [name for name in name_group.iterkeys()] #create a list out of the keys in the name_group dict

first_name = random.choice(names)
first_group = name_group[first_name]
print first_name, first_group

random.choice(seq)

Return a random element from the non-empty sequence seq. If seq is empty, raises IndexError.

Ответ 7

Вы можете использовать комбинацию pandas.groupby, pandas.concat и random.sample:

import pandas as pd
import random

df = pd.DataFrame({
        'Name': ['AAA', 'ABC', 'CCC', 'XYZ', 'DEF', 'YYH'],
        'Group_ID': [1,1,2,2,3,3]
     })

grouped = df.groupby('Group_ID')
df_sampled = pd.concat([d.ix[random.sample(d.index, 1)] for _, d in grouped]).reset_index(drop=True)
print df_sampled

Вывод:

   Group_ID Name
0         1  AAA
1         2  XYZ
2         3  DEF

Ответ 8

это не помогло, это зрелище не ответило на мои поиски, чтобы узнать, как случайным образом генерировать значение для каждой категории в python