Невозможно произвольно назначить ** в день в наборе данных ** лиц на 3 группы в соответствии с требуемым процентом - 10% / 45% / 45% - PullRequest
2 голосов
/ 14 марта 2019

Я хочу случайным образом распределить лиц из существующего набора данных в 3 разные группы в соответствии с фиксированным ежедневным процентом .Ниже приведен пример набора данных:

 Date               Customer_ID
 1. 1/3/2019         411
 2. 1/3/2019         414
 3. 1/3/2019         421
 4. 5/3/2019         431
 5. 5/3/2019         433
 6. 5/3/2019         441
 7. 6/3/2019         442
 8. 6/3/2019         443
 9. 6/3/2019         444

Я использовал приведенный ниже код Python для создания групп.Хотя общий процент трафика является правильным, группы назначены неправильно в соответствии с необходимым процентом в день .

Group   %
 A    10%
 B    45%
 C    45%

              Expected outcome               Actual outcome
 Date      Group A  Group B Group C     Group A Group B Group C
  1/3/2019  10%      45%    45%           7%    2%       91%
  1/4/2019  10%      45%    45%           12%   25%      63%
  1/5/2019  10%      45%    45%           15%   50%      35%
  1/6/2019  10%      45%    45%           20%   61%      19%
  1/7/2019  10%      45%    45%           2%    7%       91%
  1/8/2019  10%      45%    45%           1%    12%      87%
  1/9/2019  10%      45%    45%           9%    21%      70%
  1/10/2019 10%      45%    45%           13%   25%      62%
  Overall   10%      45%    45%           10%   45%      45%

Текущий код:

# Create 3 different groups that have traffic assigned 10%/45%/45%
df['Groups'] = df.groupby('Date')['Customer_ID']\
.transform(lambda x: np.random.choice(['Group_A', 'Group_B', 'Group_C'],
                                      len(x),  p= [0.1,0.45,0.45]))

Код дает только желаемый результат в общем наборе данных, но не в день (как показано в таблице фактических результатов)

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

1 Ответ

1 голос
/ 14 марта 2019

Хорошо, похоже, я неправильно понял вопрос в начале (долгий день).ИМХО, ваш код работает должным образом (извините, я просто сгенерировал числа вместо дат):

import pandas as pd
import numpy as np
rows = 10000
dates = np.random.choice(range(10), size = rows)
Customer_IDs = np.random.choice(range(2*rows), size = rows, replace = False)
data = np.vstack([dates, Customer_IDs]).T

df = pd.DataFrame(data, columns = ["Date", "Customer_ID"])

df['Groups'] = df.groupby('Date')['Customer_ID']\
    .transform(lambda x: np.random.choice(['Group_A', 'Group_B', 'Group_C'],
                                      len(x),  p= [0.1,0.45,0.45]))

print(df.groupby(['Date','Groups']).agg({'Date':'count'})\
    .groupby(level = 0).apply(lambda x:100 * x / float(x.sum())) )

Теперь может быть некоторая случайность, и строго 10/45/45 очень маловероятно.

Я бы посоветовал проверить вручную, какое у вас распределение на конкретную дату, и сравнить с «фактической» таблицей:

from collections import Counter
test_date = 1 # change this to '1/3/2019' for example
cntr = Counter(df[df["Date"]==test_date]["Groups"])
cntr_sum = sum(cntr.values())
print( {k: np.round(100 * v/cntr_sum, 2)
            for k,v in cntr.items()} )

PS.Надеюсь, у вас будет что-то подобное:

{'Group_B': 43.35, 'Group_C': 46.23, 'Group_A': 10.42}

Надеюсь, на этот раз я все понял!

...