You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas如何自定义DataFrame id分组下class列的0/1分布比例

自定义分组0/1比值的实现方案

核心逻辑

全量样本的class=0、class=1总量固定,id取值范围固定为0-50共51个分组,不要先全量随机分配id再调整——这种方式可调空间极小,应该先给需要自定义比值的分组预留配额,优先分配,剩余样本再随机分给剩下的分组,就能支持尽可能多的分组自定义比值。

具体操作步骤

  • 先梳理自定义规则:列清楚需要调整比值的id、对应id的期望0/1比值(0样本数/1样本数)、单id分配的总样本量。
  • 做配额可行性校验:逐个计算每个自定义id需要的0样本数、1样本数,公式为单id1样本数=round(单id总样本量/(比值+1)),单id0样本数=单id总样本量-单id1样本数。所有自定义id的0样本数总和不能超过全局总0样本量66932,1样本数总和不能超过全局总1样本量46337,超出的话就调小对应id的样本量,或者调整比值到合理范围。
  • 优先分配自定义分组样本:把原数据集拆成class=0、class=1两个独立样本池,对每个自定义id,从两个池子里无放回抽取对应数量的样本,打上对应的id标签,抽中的样本直接从样本池里移除,避免重复分配。
  • 分配剩余样本:两个样本池剩下的样本合并,随机分配给没有设置自定义规则的id,这部分分组的0/1比值会自然贴近全局1.444的水平,不会打乱自定义分组的比值。

最大化可调分组数量的技巧

  • 自定义分组的单组样本量不要设置过大,单组样本量控制在1000-2000区间时,51个分组里最多可以支持45个以上的分组做自定义比值调整,只要总配额不超全局上限即可。
  • 如果要设置极端比值(比如某分组全为0、全为1),尽量把这类分组的样本量设小(比如几百条),减少对全局配额的占用,留出更多空间给其他自定义分组。

参考实现代码

import pandas as pd
import numpy as np

# 初始化样本池,替换成你自己的数据集读取逻辑即可
# df = pd.read_csv('your_dataset.csv')
class0_pool = df[df['class'] == 0].reset_index(drop=True)
class1_pool = df[df['class'] == 1].reset_index(drop=True)

# 自定义规则格式:{id值: (目标0/1比值, 该id总样本量)}
custom_id_rules = {
    0: (3.2, 1600),
    1: (0.7, 1800),
    2: (2.5, 1200),
    # 按需补充更多自定义id规则
}
assigned_list = []
used_ids = set(custom_id_rules.keys())

# 先分配自定义id的样本
for cid, (target_ratio, sample_total) in custom_id_rules.items():
    n1 = round(sample_total / (target_ratio + 1))
    n0 = sample_total - n1
    # 无放回抽样
    s0 = class0_pool.sample(n=n0, replace=False)
    s1 = class1_pool.sample(n=n1, replace=False)
    # 打id标签
    s0['id'] = cid
    s1['id'] = cid
    assigned_list.append(pd.concat([s0, s1]))
    # 从样本池移除已分配样本
    class0_pool = class0_pool.drop(s0.index).reset_index(drop=True)
    class1_pool = class1_pool.drop(s1.index).reset_index(drop=True)

# 分配剩余样本
rest_samples = pd.concat([class0_pool, class1_pool]).reset_index(drop=True)
# 取出未做自定义设置的id列表
available_ids = [i for i in range(51) if i not in used_ids]
# 随机分配id
rest_samples['id'] = np.random.choice(available_ids, size=len(rest_samples))

# 合并得到最终结果
final_df = pd.concat(assigned_list + [rest_samples]).reset_index(drop=True)

运行时如果出现抽样数量超过池子剩余量的报错,说明自定义规则的总配额超了全局上限,对应调小自定义id的样本量或者调整比值即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:09:21