Excel中按约束规则为千条数据随机分组的技术咨询
按权重降序数据的规则化随机分组解决方案
我太懂这种挫败感了——手里一千行按权重从高到低排好的数据,要分到随机分组里还得守着特定规则,试了各种办法都没成,网上翻遍也找不到靠谱方案,确实头疼。
先默认你最常见的需求是让各组的总权重尽可能均衡(毕竟这种场景下把高权重数据分散开是核心),如果你的规则是其他类型(比如每组固定数量、特定数据不能同组等),可以补充说明后我再调整方案。
核心思路
因为你的数据已经按Weight降序排好了,我们可以用「贪心分配+随机微调」的组合方式,既保证规则(比如权重均衡),又能实现随机性:
- 先把权重最高的N个数据(N=分组数)分别丢进不同组,避免高权重集中在某一组
- 剩下的数据先随机打乱,再依次放进当前总权重最小的组,保证各组权重不会差太多
- 最后可以做少量组间数据交换,在不破坏规则的前提下进一步提升随机性
Python 实现示例
下面是可以直接复用的代码,你可以根据自己的分组数、数据来源(比如CSV、Excel)调整:
import random from collections import defaultdict # 模拟你的数据,实际可以用pandas从CSV/Excel读取 data = [ {"Key": 1, "Description": "Orange", "Weight": 0.987}, {"Key": 2, "Description": "Apple", "Weight": 0.876}, {"Key": 3, "Description": "Melon", "Weight": 0.765}, {"Key": 4, "Description": "Peach", "Weight": 0.654}, {"Key": 5, "Description": "Mango", "Weight": 0.432}, {"Key": 6, "Description": "Banana", "Weight": 0.321}, {"Key": 7, "Description": "Kiwi", "Weight": 0.219}, # 这里可以扩展到1000条数据 ] # 自定义分组数量,比如分成3组 group_count = 3 # 初始化分组结构:每个组存数据列表和总权重 groups = {} for i in range(group_count): groups[f"Group {i+1}"] = {"data": [], "total_weight": 0.0} # 第一步:把前N个最高权重数据分到不同组,避免集中 for idx in range(group_count): if idx >= len(data): break item = data[idx] target_group = f"Group {idx+1}" groups[target_group]["data"].append(item) groups[target_group]["total_weight"] += item["Weight"] # 剩下的数据从第N个开始处理 remaining_data = data[group_count:] # 第二步:随机打乱剩余数据,再依次放入当前权重最小的组 random.shuffle(remaining_data) for item in remaining_data: # 找到当前总权重最小的组 sorted_groups = sorted(groups.items(), key=lambda x: x[1]["total_weight"]) target_group = sorted_groups[0][0] groups[target_group]["data"].append(item) groups[target_group]["total_weight"] += item["Weight"] # 可选:做10%数据的组间交换,提升随机性且不破坏权重均衡 swap_count = int(len(data) * 0.1) for _ in range(swap_count): # 随机选两个不同的组 group_keys = list(groups.keys()) group_a, group_b = random.sample(group_keys, 2) # 确保两个组都有数据可交换 if not groups[group_a]["data"] or not groups[group_b]["data"]: continue # 从每组随机选一个数据 item_a = random.choice(groups[group_a]["data"]) item_b = random.choice(groups[group_b]["data"]) # 检查交换后权重差异是否变大,变大就不交换 original_diff = abs(groups[group_a]["total_weight"] - groups[group_b]["total_weight"]) new_diff = abs( (groups[group_a]["total_weight"] - item_a["Weight"] + item_b["Weight"]) - (groups[group_b]["total_weight"] - item_b["Weight"] + item_a["Weight"]) ) if new_diff <= original_diff: # 执行交换 groups[group_a]["data"].remove(item_a) groups[group_a]["data"].append(item_b) groups[group_a]["total_weight"] = groups[group_a]["total_weight"] - item_a["Weight"] + item_b["Weight"] groups[group_b]["data"].remove(item_b) groups[group_b]["data"].append(item_a) groups[group_b]["total_weight"] = groups[group_b]["total_weight"] - item_b["Weight"] + item_a["Weight"] # 输出分组结果 for group_key, group_info in groups.items(): print(f"\n{group_key} 总权重: {group_info['total_weight']:.3f}") for item in group_info["data"]: print(f" Key: {item['Key']}, Description: {item['Description']}, Weight: {item['Weight']:.3f}")
其他规则适配说明
如果你的规则不是权重均衡,比如:
- 每组固定数量的条目
- 某些特定描述的数据不能在同一组
- 分组需要满足其他业务逻辑
可以把具体规则补充出来,我再帮你调整代码逻辑~
内容的提问来源于stack exchange,提问作者JIT
相关产品推荐
相关产品推荐

