У меня есть DataFrame c
, содержащий столбцы a
.
import numpy as np
a = np.random.randint(0,10, size=(100))
c = pd.DataFrame(a, columns=['a'])
Я хочу сделать случайную группировку строк c
так, чтобы в каждой группе было 5 строк и чтобы в каждой группе была 1 строка с a < 3
так, например:
[1,2,3,2,10] <-- good group
[1,1,3,4,6] <-- good group
[2,4,7,3,7] <-- bad group
И если у меня закончились строки, чтобы соответствовать этим критериям (например, у меня закончились строки с a < 1
), игнорируйте остальную часть фрейма данных
В настоящее время я делаю это, создавая новый столбец group_id
и отделяя c
по условию, а затем итеративно выбирая из них, пока у меня не закончатся кандидаты:
c['group_id'] = None
c_w_small_a = c[c.a < 3].copy()
c_w_large_a = c[c.a >= 3].copy()
group_id = 0
while len(c_w_small_a) >= 1 and len(c_w_large_a) >= 4:
c.loc[c_w_small_a.sample(1, replace=False).index, 'group_id'] = group_id
c.loc[c_w_large_a.sample(4, replace=False).index, 'group_id'] = group_id
group_id += 1
c = c[c.group_id.apply(lambda x,x is not None)] # filter rows without id
c_groups = c.groupby('group_id')
Проблема с этим подходом в том, что я могу ' Обобщим этот подход более сложным условием, при котором подмножества перекрывают друг друга. например,
не более 2 строк с a > 2
и не менее 1 строки с 'a == 3'.
Я не знаю, как это кодировать таким образом, чтобы максимально увеличить количество групп, которые я могу получить с помощью этой группировки. Например, если a == 3 очень ограничено, я не хочу, чтобы a> 2 выбирал 3, даже если это удовлетворяет его условию.