Pandas按权重进行抽样

13

我有一个df,我想根据某个变量的分布对它进行抽样。假设df ['type'] .value_counts(normalize=True)返回:

A 0.3
B 0.5
C 0.2

我想做类似于sampledf = df.sample(weights=df['type'].value_counts(normalize=True))的东西,使得sampledf ['type'].value_counts(normalize=True)返回几乎相同的分布。如何在此处传递具有频率的字典?

3个回答

18

Weights必须采用与原始df相同长度的系列数据,最好将其添加为列:

df['freq'] = df.groupby('type')['type'].transform('count')
sampledf = df.sample(weights = df.freq)

或者不添加该列:

sampledf = df.sample(weights = df.groupby('type')['type'].transform('count'))

4
除了上面的答案之外,还应该注意如果你想平等地采集每种类型,你应该调整你的代码为:
df['freq'] = 1./df.groupby('type')['type'].transform('count')
sampledf = df.sample(weights = df.freq)

如果有两个类别,则可以使用以下代码来推广权重计算方法:

如果您有多于两个类别,您可以使用以下代码来通用化权重计算:

w_j=n_samples / (n_classes * n_samples_j)

0

不需要创建“与原始 df 长度相同的一系列数据”。相反,您可以通过传递 value_counts 的分组输出来从每个组中进行抽样,如下所示:

col = 'type'
sample_factor = .3
# sample size per group
weights = (df[col].value_counts() * sample_factor).astype(int)
df.groupby(col).apply(lambda g: g.sample(n=weights[g.name]))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接