выборка с учётом распределения признака в другой таблице
Есть df1 в формате
df1 = pd.DataFrame({'id': [1, 2, 3, 4, 5, 6],
'group': ['a', 'a', 'a', 'b', 'b', 'c']})
В df1 признак group распределяется следующим образом:
df1.group.value_counts(normalize=True,dropna = False)
a - 0.50000
b - 0.33333
c - 0.16667
Есть df2 в аналогичном формате, но с другим распределением признака group.
df2 = pd.DataFrame({'id': [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
'group': ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'b', 'c', 'c']})
В df2 признак group распределяется следующим образом:
df2.group.value_counts(normalize=True,dropna = False)
c - 0.45455
b - 0.27273
a - 0.27273
Задача: сделать максимально большую подвыборку из df2, чтобы в этой подвыборке распределение признака group было бы такое же, как в df1. Если невозможно максимально большую, то хотя бы подвыборку любого размера.
Ответы (1 шт):
Попробуйте так.
Правда немного громоздко вышло.
Смотрим на распределение:
rate = df1['group'].value_counts(normalize=True, dropna=False)
найдем максимальное значение
val = rate.max()
Создадим из распределения фрейм, а затем найдем для какой переменной это значение является максимальным, а на случай, если максимальное значение принадлежит нескольким переменным, то возьмем первое.
df_max = pd.DataFrame(rate)
max_gr = df_max[df_max.group == val].index.values[0]
Далее найдем количество этой переменной во втором фрейме, который будем семплировать по распределению первого фрейма.
count_of_max = df2[df2.group == max_gr]['group'].count()
и теперь коэффициент
koef = count_of_max/rate[max_gr]
и наконец сама выборка с аналогичным распределением.
sample_df = df2.groupby('group').apply(lambda x: x.sample(int(koef * rate[x.name]))).reset_index(drop=True)
>>> sample_df
id group
0 12 a
1 11 a
2 13 a
3 19 b
4 14 b
5 20 c
по идее все решение в последней строчке, но самое интересное, это найти этот коэффициент, чтобы получить выборку с распределением максимального размера.