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

如何用Python对含ID与性别的数据集实现Disproportional Stratified Sampling组建团队?

非比例分层抽样组建团队的Python实现

第一步:修正数据读取代码

你的原代码存在变量名错误(inc、onc应为gr、gend),先修正这段代码以正确获取各分层的人数分布:

from openpyxl import load_workbook

wb = load_workbook("dataset.xlsx")
sh = wb["Page"]
dist = []
# 遍历415条数据行
for i in range(415):
    gr = sh[f'C{i+1}'].value  # 分配ID(1-8)
    gend = sh[f'D{i+1}'].value  # 性别(M/F)
    dist.append(f"{int(gr)}{gend}")

# 输出各分层人数统计
for grade in range(1, 9):
    male_count = dist.count(f"{grade}M")
    female_count = dist.count(f"{grade}F")
    print(f"分配ID {grade} 男性人数: {male_count}")
    print(f"分配ID {grade} 女性人数: {female_count}")

第二步:实现非比例分层抽样

非比例分层抽样的核心是不按原分层比例分配样本量,而是根据需求自定义每个分层的抽取数量(比如给小群体分配更多样本以保证代表性)。下面用pandas+sklearn实现高效抽样:

1. 导入数据为DataFrame

import pandas as pd

# 读取Excel数据,指定列名简化后续操作
df = pd.read_excel("dataset.xlsx", sheet_name="Page", usecols=["C", "D"], names=["分配ID", "性别"])
df["分配ID"] = df["分配ID"].astype(int)  # 确保分配ID为整数类型

2. 定义各分层的抽样数量

根据团队需求指定每个(分配ID, 性别)分层要抽取的人数,示例中给每个分层固定抽5人:

sample_sizes = {
    (1, "M"): 5, (1, "F"): 5,
    (2, "M"): 5, (2, "F"): 5,
    (3, "M"): 5, (3, "F"): 5,
    (4, "M"): 5, (4, "F"): 5,
    (5, "M"): 5, (5, "F"): 5,
    (6, "M"): 5, (6, "F"): 5,
    (7, "M"): 5, (7, "F"): 5,
    (8, "M"): 5, (8, "F"): 5,
}

3. 执行抽样

from sklearn.model_selection import StratifiedShuffleSplit

# 创建分层标识列,用于区分不同分层
df["分层标识"] = df["分配ID"].astype(str) + df["性别"]

sampled_df = pd.DataFrame()
splitter = StratifiedShuffleSplit(n_splits=1, test_size=None)

# 遍历每个分层执行抽样
for strat, size in sample_sizes.items():
    strat_id, strat_gender = strat
    # 筛选当前分层的数据
    strat_data = df[(df["分配ID"] == strat_id) & (df["性别"] == strat_gender)]
    
    if len(strat_data) >= size:
        # 随机抽取指定数量样本
        _, sample_idx = next(splitter.split(strat_data, strat_data["分层标识"]))
        sampled = strat_data.iloc[sample_idx[:size]]
        sampled_df = pd.concat([sampled_df, sampled], ignore_index=True)
    else:
        # 若分层人数不足,直接纳入全部数据
        print(f"警告:分层({strat_id}, {strat_gender})仅{len(strat_data)}人,不足{size}人,已全部纳入样本")
        sampled_df = pd.concat([sampled_df, strat_data], ignore_index=True)

# 输出抽样结果并保存
print("抽样后的团队数据:")
print(sampled_df)
sampled_df.to_excel("抽样团队.xlsx", index=False)

关键说明

  • 你可以根据实际需求调整sample_sizes字典,比如给人数较少的分层分配更多样本,或针对特定分层调整抽取数量。
  • 若不想依赖sklearn,可直接用pandas的sample方法:对每个分层调用strat_data.sample(n=size, random_state=42)(random_state保证抽样结果可复现)。
  • 用pandas读取数据无需硬编码行数,适配数据量变化更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:30:33