如何从DataFrame抽取保留变量分布的随机样本?(Python)
解决方案:带分组保证的随机抽样
直接使用df.sample(100, random_state=20)无法确保每个国家都有样本被选中,因为纯随机抽样可能会遗漏样本量较小的国家。可以通过分层抽样+保底抽取的方式实现需求,具体步骤如下:
方法一:保底1个样本+剩余随机分配
这种方法先确保每个国家至少有1条样本,剩余名额从排除已抽样本的数据中随机抽取,保证总样本数为100。
代码实现
import pandas as pd # 获取所有唯一国家 unique_countries = df['国家'].unique() country_count = len(unique_countries) # 处理国家数量超过100的特殊情况(无法满足每个国家至少1个样本) if country_count > 100: raise ValueError("国家数量超过100,无法保证每个国家都有样本被抽取") # 每个国家先抽取1个样本 base_sample = df.groupby('国家', group_keys=False).apply(lambda group: group.sample(n=1, random_state=20)) # 计算剩余需要抽取的样本数量 remaining_samples_needed = 100 - country_count # 从剩余数据中抽取剩余名额 remaining_sample = df.drop(base_sample.index).sample(n=remaining_samples_needed, random_state=20) # 合并得到最终样本 final_sample = pd.concat([base_sample, remaining_sample]).reset_index(drop=True)
说明
- 先通过
groupby+apply给每个国家分配1个样本,确保没有国家被遗漏; - 从原数据中移除已抽取的样本,再随机抽取剩余名额,保证总样本数为100;
random_state=20用于固定随机种子,保证结果可复现。
方法二:按比例分层抽样(适配大样本量)
如果希望样本中各国家的比例尽量贴近原数据,同时保证每个国家至少1个样本,可以调整抽取逻辑:
代码实现
import pandas as pd unique_countries = df['国家'].unique() country_count = len(unique_countries) if country_count > 100: raise ValueError("国家数量超过100,无法保证每个国家都有样本被抽取") # 计算每个国家的理想抽取数量(按原数据比例分配) country_sample_counts = (df['国家'].value_counts(normalize=True) * 100).round().astype(int) # 确保每个国家至少1个样本,调整总数量到100 country_sample_counts = country_sample_counts.clip(lower=1) total = country_sample_counts.sum() diff = 100 - total # 调整差额(给样本量较大的国家加减) if diff > 0: # 给样本量多的国家加名额 top_countries = country_sample_counts.sort_values(ascending=False).index[:diff] country_sample_counts[top_countries] += 1 elif diff < 0: # 给样本量多的国家减名额(但保留至少1个) top_countries = country_sample_counts[country_sample_counts > 1].sort_values(ascending=False).index[:-diff] country_sample_counts[top_countries] -= 1 # 按计算的数量抽取样本 final_sample = df.groupby('国家', group_keys=False).apply(lambda group: group.sample(n=country_sample_counts[group.name], random_state=20)) final_sample = final_sample.reset_index(drop=True)
说明
这种方法会尽量保持原数据中国家的分布比例,同时强制每个国家至少有1个样本,适合需要保持分布特征的场景。
内容的提问来源于stack exchange,提问作者codingrainha
相关产品推荐
相关产品推荐

