Python: стратифицированная выборка по несбалансированным данным с соотношением - PullRequest
0 голосов
/ 15 января 2020

Вот мой фрейм данных:

df = pd.DataFrame({'var1': [1,2,3,4,5,6,7,8,9,10,11,12,13,14],
                   'var2': ['a','a','a','a','b','b','b','b','b','b','b','c','d','d'],
                   'var3': ['y','y','y','y','r','r','r','r','r','r','r','q','q', 'r'],
                   'var4': [0,1,0,0,1,1,0,0,0,0,0,0,0,0]})

, поскольку var4 не сбалансирован. Я планирую взять каждую var4 = 1 и удвоенную сумму var4 = 0 в зависимости от группы var2 и var3. В результате у группы 'a' 'y' будет один '1' и два '0'; группа 'b''r' будет иметь два '1' и 4 '0'. Другие группы не будут иметь ни одной. Выглядит как показано ниже:

df_sampled = pd.DataFrame({'var1': [1,2,3,5,6,7,8,10,11],
                   'var2': ['a','a','a','b','b','b','b','b','b'],
                   'var3': ['y','y','y','r','r','r','r','r','r'],
                   'var4': [0,1,0,1,1,0,0,0,0]})

Я попытался выяснить размер var4 = 1 для каждой группы:

df.var4 = df.var4.mask(df.var4.ne(1))
dd = df.groupby(['var2', 'var3']).var4.count().tolist()

Я также попытался использовать sample() для запуска в списке дд:

df.loc[df['var4'] == 0].groupby(['var2','var3'], group_keys=False).apply(lambda x: x.sample(dd))

Однако это не работает. Есть предложения?

1 Ответ

0 голосов
/ 15 января 2020

Давайте попробуем так. Сортировка df по пу sh все 1 к началу. cumcount в группе var1 и var2 для использования в качестве счетчика. Получение суммы каждой группы (поскольку значения var4 равны только 0 и 1, сумма каждой группы - это число 1 в каждой группе). Наконец, нарезать строки, где счетчик меньше или равен двойной сумме.

df = df.sort_values('var4', ascending=False)
gb = df.groupby(['var2', 'var3'])
s = gb.cumcount().add(1)
s1 = gb.var4.transform('sum')
df_final =  df[(s - s1) <= (s1 * 2)].sort_index()

Out[1758]:
   var1 var2 var3  var4
0     1    a    y     0
1     2    a    y     1
2     3    a    y     0
4     5    b    r     1
5     6    b    r     1
6     7    b    r     0
7     8    b    r     0
8     9    b    r     0
9    10    b    r     0
...