You need to enable JavaScript to run this app. 使用pandas groupby按比例抽样时,如何保留所有极小分组?
优惠活动
大模型
产品
解决方案
定价
更多

使用pandas groupby按比例抽样时,如何保留所有极小分组?

问题根因

你遇到的小分组完全未进入抽样结果的问题,本质是pandas sample 方法的内置处理逻辑导致的:

  • 当传入frac参数时,pandas会先计算每个分组的实际抽样条数 = 分组总样本量 × 抽样比例
  • 若计算出的抽样条数不足1,会直接返回空样本,不会做向上取整或者兜底处理
    在你的示例数据里,b=1的分组总共只有1条样本,按0.1比例算得需要抽0.1条,不足1条就被直接舍弃,自然不会出现在最终结果里。
调整实现方案

方案1:自定义逐组抽样逻辑,设置抽样数最小阈值

不再直接传frac参数让pandas自动计算抽样数,而是在分组内手动计算每个组的目标抽样数,给抽样数设置最小为1的兜底值——只要分组非空,哪怕按比例算出的抽样数不足1,也至少抽1条,从根源上避免小分组被完全漏掉。

# 固定抽样比例
sample_frac = 0.1
# 固定随机种子保证结果可复现
df1 = df.groupby('b', group_keys=False).apply(
    lambda g: g.sample(
        n = min(
            len(g), # 抽样数不能超过组本身的总样本量
            max(1, round(len(g) * sample_frac)) # 抽样数最少为1
        ),
        random_state=42
    )
).reset_index(drop=True)

逻辑说明:

  • 对b=0的大分组(12条样本),按0.1比例算出需要抽1条,和原逻辑的抽样规模一致
  • 对b=1的小分组(1条样本),按0.1比例算出需要抽0.1条,触发兜底逻辑至少抽1条,因为组总共只有1条,最终会把整个组保留,完全符合需求。
  • 附带的group_keys=False参数会关闭分组键索引的生成,避免结果出现多层索引,让后续的reset_index操作更顺畅。

方案2:分块处理大小分组(大表性能更优)

如果是数据量百万级以上的大表,逐组在apply内计算抽样数会有额外性能开销,可以直接把小分组和大分组拆成两部分处理,最后合并结果:

sample_frac = 0.1
# 统计每个分组的总样本量
group_size_stat = df.groupby('b').size()
# 筛选出“按比例抽样肯定抽不到”的小分组:len(g)*frac < 1
small_group_keys = group_size_stat[group_size_stat * sample_frac < 1].index
# 小分组直接全量保留
small_sample = df[df['b'].isin(small_group_keys)]
# 剩余大分组按原逻辑正常按比例抽样
big_sample = df[~df['b'].isin(small_group_keys)].groupby(
    'b', group_keys=False
).apply(lambda g: g.sample(frac=sample_frac, random_state=42))
# 合并两部分抽样结果
df1 = pd.concat([small_sample, big_sample]).reset_index(drop=True)

注意:如果你的需求是“只要分组样本量极小,不管算出来的抽样数是多少,都要全量保留”,可以调整小分组的判定阈值(比如把判定条件改成len(g) < 5就全量保留),不用完全绑定抽样比例的计算结果。


内容的提问来源于stack exchange,提问作者Feng Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 15:15:04