我有一个数据集,每个ID有多行数据。大约有5000个ID,每个ID可以有1到22行数据,每行属于一个不同的组。我想从每个ID中抽样1行,并希望抽样数据在组中均匀分布。
这是一个虚拟的df
,它被简化为有8个ID,每个ID可以有1到4行数据:
id group
1 a
1 b
1 c
1 d
2 a
2 b
3 a
3 b
3 c
3 d
4 a
4 b
4 d
5 a
5 b
5 c
5 d
6 a
6 d
7 a
7 b
7 d
8 a
8 b
8 c
8 d
由于有8个ID和4个组,我希望采样数据具有来自每个组的2个ID。数字2只是因为我希望在组中均匀分布,所以如果有20个ID和4个组,我希望采样数据有来自每个组的5个ID。另外,我想从每个ID中采样一行,因此所有ID应该在采样数据中出现一次。有办法做到这一点吗?
我尝试在pd.DataFrame.sample
中使用权重,使用每个组的1/频率作为权重,希望频率较低的组中的行将具有更大的权重,因此被采样的机会更高,这样最终采样的数据将在组中大致均匀分布。但它并没有像我预期的那样奏效。我尝试使用不同的随机状态,但它们都没有给出在组中均匀分布的采样数据集。这是我使用的代码:
# Create dummy dataframe:
d = {'id': [1,1,1,1,
2,2,
3,3,3,3,
4,4,4,
5,5,5,5,
6,6,
7,7,7,
8,8,8,8],
'group': ['a','b','c','d',
'a','b',
'a','b','c','d',
'a','b','d',
'a','b','c','d',
'a','d',
'a','b','d',
'a','b','c','d']}
df = pd.DataFrame(data=d)
# Calculate weights
df['inverted_freq'] = 1./df.groupby('group')['group'].transform('count')
# Sample one row from each ID
df1 = df.groupby('id').apply(pd.DataFrame.sample, random_state=1, n=1, weights=df.inverted_freq).reset_index(drop=True)
我的预期产出是:
id group
1 d
2 b
3 a
4 d
5 c
6 a
7 b
8 c
或者类似的东西,每个ID占一行,每个组占相等的行数。
无论是用R语言还是用Python语言提出建议,我们都将不胜感激。谢谢!
暂无答案!
目前还没有任何答案,快来回答吧!