Как случайным образом генерировать ненаблюдаемые данные в Python3 - PullRequest
0 голосов
/ 24 февраля 2019

У меня есть фрейм данных, который содержит данные наблюдений в виде:

import pandas as pd
d = {'humanID': [1, 1, 2,2,2,2 ,2,2,2,2], 'dogID': 
[1,2,1,5,4,6,7,20,9,7],'month': [1,1,2,3,1,2,3,1,2,2]}
df = pd.DataFrame(data=d)

Следуют df

    humanID  dogID  month
0        1      1      1
1        1      2      1
2        2      1      2
3        2      5      3
4        2      4      1
5        2      6      2
6        2      7      3
7        2     20      1
8        2      9      2
9        2      7      2

Всего у нас два human и двадцать dogи выше df содержит наблюдаемые данные.Например:

Первый ряд означает: human1 принять dog1 в январе

Второй ряд означает: human1 принять dog2 в январе

третий ряд означает: human2 принять dog1 в феврале

==============================================================================

Моя цельслучайным образом генерирует two ненаблюдаемые данные для каждого (human, month), которые не появляются в исходных наблюдаемых данных.

как для human1 в January, он не принимает собаку [3,4,5,6,7,..20] И яхотите случайным образом создать два ненаблюдаемых образца (human, month) в тройной форме

humanID dogID month
   1      20    1
   1      10    1

Однако следующий образец не допускается, поскольку он отображается в оригинале df

  humanID dogID month
   1        2    1

Для human1 у него нет активности в феврале, поэтому нам не нужно выбирать ненаблюдаемые данные.

Для human2 у него активность за январь, февраль и март.Поэтому для каждого месяца мы хотим случайным образом создавать ненаблюдаемые данные.Например, в январе human2 принимает dog1, dog4 и god 20.Две случайные ненаблюдаемые выборки могут быть

humanID dogID month
   2      2    1
   2      6    1

. Один и тот же процесс может быть использован для февраля и марта.

Я хочу поместить все ненаблюдаемые данные в один кадр данных, например: unobserved

    humanID  dogID  month
0        1      20      1
1        1      10      1
2        2      2       1
3        2      6       1
4        2      13      2
5        2      16      2
6        2      1       3
7        2      20      3

Есть ли быстрый способ сделать это?

PS: это кодовое интервью для начинающей компании.

Ответы [ 2 ]

0 голосов
/ 24 февраля 2019

Использование groupby и random.choices:

import random

dogs = list(range(1,21))
dfs = []
n_sample = 2
for i,d in df.groupby(['humanID', 'month']):
    h_id, month = i
    sample = pd.DataFrame([(h_id, dogID, month) for dogID in random.choices(list(set(dogs)-set(d['dogID'])), k=n_sample)])
    dfs.append(sample)
new_df = pd.concat(dfs).reset_index(drop=True)
new_df.columns = ['humanID', 'dogID', 'month']

print(new_df)
   humanID  dogID  month
0        1     11      1
1        1      5      1
2        2     19      1
3        2     18      1
4        2     15      2
5        2     14      2
6        2     16      3
7        2     18      3
0 голосов
/ 24 февраля 2019

Если я вас правильно понимаю, вы можете использовать np.random.permutation() для столбца dogID для генерации случайных перестановок столбца,

df_new=df.copy()
df_new['dogID']=np.random.permutation(df.dogID)
print(df_new.sort_values('month'))

   humanID  dogID  month
0        1      1      1
1        1     20      1
4        2      9      1
7        2      1      1
2        2      4      2
5        2      5      2
8        2      2      2
9        2      7      2
3        2      7      3
6        2      6      3

Или для созданияслучайная выборка пропущенных значений в диапазоне dogID:

df_new=df.copy()
a=np.random.permutation(range(df_new.dogID.min(),df_new.dogID.max()))
df_new['dogID']=np.random.choice(a,df_new.shape[0])
print(df_new.sort_values('month'))

   humanID  dogID  month
0        1     18      1
1        1     16      1
4        2      1      1
7        2      8      1
2        2      4      2
5        2      2      2
8        2     16      2
9        2     14      2
3        2      4      3
6        2     12      3
...