如何在 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
未观测数据。
喜欢 January
的 human1
,他没有收养狗 [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
采用dog1
、dog4
和god 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
使用 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
我有一个包含观察数据的数据框:
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
未观测数据。
喜欢 January
的 human1
,他没有收养狗 [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
采用dog1
、dog4
和god 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
使用 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