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

Groupby分组后将小样本小组合并至相邻小组的技术问询

解决方案:无需字典的相邻小组合并方法

嘿,我来给你一个完全符合需求的实现方案——不用手动创建任何映射字典,完全基于列值和小组的索引顺序来完成合并,从样本量最小的组开始逐步合并,直到小组总数不超过10个。

核心思路

  1. 先把带MultiIndex的统计结果转换成普通列格式,方便后续操作;
  2. 循环执行合并:每次找到样本量最小的组,将其与索引顺序的下一个相邻组合并(如果是最后一组则合并到前一个);
  3. 合并时用加权平均计算新的mean(因为不同组的样本量不同,直接取平均会有偏差),count直接求和;
  4. 合并后重新排序保证小组顺序的连续性,直到总组数≤10。

具体代码实现

首先,先把你给出的初始统计结果构造成可操作的DataFrame(如果你的数据已经是DataFrame,这一步可以跳过):

import pandas as pd

# 构造你的初始分组统计结果
data = [
    [0,0,0, 0.571429,7],
    [0,0,1, 0.414634,41],
    [0,0,2, 0.428571,28],
    [0,1,0, 0.490909,55],
    [0,1,1, 0.467337,199],
    [0,1,2, 0.486726,113],
    [0,2,0, 0.518519,27],
    [0,2,1, 0.446281,121],
    [0,2,2, 0.541667,72]
]
stats_df = pd.DataFrame(data, columns=['f1','f2','f3','mean','count']).set_index(['f1','f2','f3'])

然后是合并逻辑的核心代码:

# 重置索引为普通列,方便后续操作
working_df = stats_df.reset_index().copy()

# 循环直到小组总数不超过10个
while len(working_df) > 10:
    # 找到样本量最小的组的位置
    min_count_idx = working_df['count'].idxmin()
    
    # 处理边界情况:如果是最后一组,就合并到前一个组,否则合并到下一个相邻组
    if min_count_idx == len(working_df) - 1:
        merge_target_idx = min_count_idx - 1
    else:
        merge_target_idx = min_count_idx + 1
    
    # 获取要合并的两个组的数据
    group_min = working_df.loc[min_count_idx]
    group_neighbor = working_df.loc[merge_target_idx]
    
    # 计算合并后的加权平均mean和总count
    merged_mean = (group_min['mean'] * group_min['count'] + group_neighbor['mean'] * group_neighbor['count']) / (group_min['count'] + group_neighbor['count'])
    merged_count = group_min['count'] + group_neighbor['count']
    
    # 构造合并后的分组标识:相同列值保留原值,不同列值用范围元组表示(比如f3从0到1就写成(0,1))
    merged_groups = {}
    for col in ['f1', 'f2', 'f3']:
        if group_min[col] == group_neighbor[col]:
            merged_groups[col] = group_min[col]
        else:
            merged_groups[col] = (min(group_min[col], group_neighbor[col]), max(group_min[col], group_neighbor[col]))
    
    # 创建合并后的行数据
    merged_row = pd.Series({
        **merged_groups,
        'mean': merged_mean,
        'count': merged_count
    })
    
    # 删除原有的两个组,添加合并后的新组
    working_df = working_df.drop([min_count_idx, merge_target_idx]).reset_index(drop=True)
    working_df = pd.concat([working_df, merged_row.to_frame().T], ignore_index=True)
    
    # 重新按原分组顺序排序,保证后续合并的相邻性正确
    working_df = working_df.sort_values(by=['f1','f2','f3']).reset_index(drop=True)

# 可选:将结果恢复为MultiIndex格式(如果需要)
final_stats = working_df.set_index(['f1','f2','f3'])
print(final_stats)

关键细节说明

  • 加权平均的必要性:直接对两个组的mean取平均是不准确的,因为样本量多的组对整体均值的影响更大,所以必须用样本量作为权重计算加权平均;
  • 边界处理:当最小样本量的组是最后一个时,合并到前一个组,避免索引越界;
  • 分组标识的可读性:合并后的分组键会用范围元组体现合并的列值范围,比如(0,1)表示这个组包含了原f3为0和1的两个小组,方便你直观理解合并结果;
  • 自动循环终止:只要总组数超过10,就会持续合并最小样本量的组,直到满足条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:50:01