如何在 Python3 中随机生成一个未观察到的数据

How to randomly generate an unobserved data in Python3

我有一个包含观察数据的数据框:

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领养

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

我的目标是为每个未出现在原始观测数据中的 (human, month) 随机生成 two 未观测数据。

喜欢 Januaryhuman1,他没有收养狗 [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,他在2月份没有任何activity,所以我们不需要对未观察到的数据进行采样。

对于 human2,他在一月、二月和三月有 activity。因此,对于每个月,我们都想随机创建未观察到的数据。例如,一月,human2采用dog1dog4god 20。两个随机未观察样本可以是

humanID dogID month
   2      2    1
   2      6    1

2 月和 3 月可以使用相同的过程。

我想将所有未观察到的数据放在一个数据框中,例如 follow 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:这是一家初创公司的代码面试。

如果我没理解错的话,您可以对 dogID 列使用 np.random.permutation() 来生成该列的随机排列,

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

使用 groupbyrandom.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