如何用Python实现随机分层抽样(非训练/测试拆分)
无监督场景下的Pandas随机分层抽样实现方案
没问题!针对你这种调查、民意测验场景的分层抽样需求,完全可以用Pandas原生方法搞定,不用依赖sklearn那些面向监督学习的工具。咱们直接上干货,分几种常见场景给你讲具体实现:
核心思路
分层抽样的本质是先按照你关心的维度(比如年龄组、地域、职业这类分层变量)把数据集拆分成不同子组,然后在每个子组里独立做随机抽样,这样能保证样本结构和总体一致,避免抽样偏差。
1. 按比例抽取样本
如果想让每个分层组都抽取相同比例的样本(比如总体的20%),可以这么写:
import pandas as pd # 假设你的数据集是df,分层列是"age_group"(比如青年/中年/老年) stratified_sample = df.groupby("age_group", group_keys=False).apply( lambda x: x.sample(frac=0.2, random_state=42) )
group_keys=False:避免把分组键(比如age_group的取值)加到结果的索引里,让输出的DataFrame结构更干净frac=0.2:表示抽取每组20%的样本,你可以根据需求调整这个比例random_state=42:固定随机种子,保证每次抽样结果完全一致,方便复现
2. 按固定数量抽取样本
如果需要每个分层组都抽取固定数量的样本(比如每个组抽50个),代码如下:
stratified_sample = df.groupby("age_group", group_keys=False).apply( lambda x: x.sample(n=50, random_state=42) )
小细节处理:组内样本数不足的情况
如果某个分层组的总样本数少于你指定的n(比如某个年龄组只有30个样本,但你想抽50个),直接运行上面的代码会报错。可以加个判断,自动取该组的全部样本:
stratified_sample = df.groupby("age_group", group_keys=False).apply( lambda x: x.sample(n=min(50, len(x)), random_state=42) )
3. 多维度分层抽样
如果需要同时按多个维度分层(比如同时按地域和职业),只需要把多个列名放进groupby的参数里就行:
# 按"region"(地域)和"occupation"(职业)双维度分层 stratified_sample = df.groupby(["region", "occupation"], group_keys=False).apply( lambda x: x.sample(frac=0.2, random_state=42) )
4. 自定义各层抽样权重
如果不同分层组需要不同的抽样比例(比如重点关注老年组,给他更高的抽样权重),可以先定义一个权重字典,再动态调用:
# 自定义各年龄组的抽样比例 sample_weights = { "青年组": 0.2, "中年组": 0.2, "老年组": 0.35 # 老年组抽取35%的样本 } stratified_sample = df.groupby("age_group", group_keys=False).apply( lambda x: x.sample(frac=sample_weights[x.name], random_state=42) )
这样就能灵活满足不同场景的抽样需求啦~
内容的提问来源于stack exchange,提问作者asl
相关产品推荐
相关产品推荐

