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

基于目标变量分桶:如何按贡献度将DSA随机划分为10个占比约10%的组

解决方案

核心思路

采用随机打乱+贪心凑数的逻辑,既保证分组的随机性,又能严格控制每组贡献的误差范围,全程无硬编码的固定阈值或列名,切换分组依据(3M/6M贡献)仅需修改传参即可,适配性极强。

前置依赖

仅需安装pandas和numpy两个通用数据处理库。

完整实现代码

1. 数据预处理

import pandas as pd
import numpy as np

# 示例数据,实际使用时替换为你的数据集读取代码(比如pd.read_csv)
df = pd.DataFrame({
    "DSA": ["ABC", "BCA", "CDE", "DCA", "EDA"],
    "3M Contribution": ["1.3%", "3.4%", "0.8%", "0.1%", "2%"],
    "6M Contribution": ["3.6%", "1.5%", "0.1%", "2%", "0.7%"]
})

# 百分比列统一转数值格式,方便后续计算
for col in ["3M Contribution", "6M Contribution"]:
    df[col] = df[col].str.replace("%", "").astype(float) / 100

2. 通用分组函数

def random_contribution_group(df, contrib_col, group_num=10, error_tolerance=0.005):
    """
    按指定贡献列随机拆分分组
    参数:
    df: 原始数据集
    contrib_col: 用于计算分组贡献的列名,可传入"3M Contribution"或"6M Contribution"
    group_num: 拆分的组数,默认10
    error_tolerance: 每组贡献允许的误差范围,默认0.005对应±0.5%
    """
    # 全量随机打乱数据集,保证分组随机性
    shuffled_df = df.sample(frac=1, random_state=None).reset_index(drop=True)
    # 计算单组目标贡献值,默认10组对应单组目标10%
    target_per_group = 1 / group_num
    groups = []
    current_group = []
    current_sum = 0.0

    for _, row in shuffled_df.iterrows():
        current_contrib = row[contrib_col]
        # 加入当前行后不超过误差上限则加入当前组
        if current_sum + current_contrib <= target_per_group + error_tolerance:
            current_group.append(row.to_dict())
            current_sum += current_contrib
            # 达到误差下限则闭合当前组,开启新组
            if current_sum >= target_per_group - error_tolerance:
                groups.append(pd.DataFrame(current_group))
                current_group = []
                current_sum = 0.0
        else:
            # 加入后超出上限则闭合当前组,当前行归入下一组
            groups.append(pd.DataFrame(current_group))
            current_group = [row.to_dict()]
            current_sum = current_contrib

    # 处理剩余未分组的行,合并到最后一组
    if current_group:
        if groups:
            groups[-1] = pd.concat([groups[-1], pd.DataFrame(current_group)], ignore_index=True)
        else:
            groups.append(pd.DataFrame(current_group))

    # 给每组打标签
    for group_id, group_df in enumerate(groups, 1):
        group_df["group_id"] = group_id

    return pd.concat(groups, ignore_index=True)

3. 调用示例

# 按3M贡献分组
result_3m = random_contribution_group(df, "3M Contribution")
# 按6M贡献分组,仅需修改contrib_col参数即可
result_6m = random_contribution_group(df, "6M Contribution")

# 验证分组结果是否符合误差要求
print("3M贡献分组统计:")
print(result_3m.groupby("group_id")["3M Contribution"].sum().round(4) * 100)

注意事项

  • 如需固定分组结果方便复现,可将sample方法中的random_state参数设置为固定整数,比如random_state=42。
  • 180个DSA的场景下几乎每次运行都能得到符合误差要求的结果,若偶发误差超标,重新运行一次即可。
  • 所有核心参数(组数、误差范围、分组依据)均支持自定义调整,无需修改内部逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:27:00