基于Pandas DataFrame实现分SECTION按权重抽取指定数量CODE
解决方案
步骤1:明确数据结构(示例)
先假设你的两个DataFrame结构如下(如果你的结构不同,只需调整列名即可):
- 权重表
weight_df:
| SECTION | CODE | Final_Per |
|---|---|---|
| B1 | 800 | 0.05 |
| B1 | 801 | 0.65 |
| B1 | 802 | 0.30 |
| A2 | 700 | 0.20 |
| A2 | 701 | 0.80 |
- 样本数量表
count_df:
| SECTION | NUMBER |
|---|---|
| B1 | 14 |
| A2 | 20 |
步骤2:合并两个表
先把两个表按SECTION合并,让每个CODE对应到所属SECTION的样本数量:
import pandas as pd # 从CSV导入数据(替换为你的文件路径) # weight_df = pd.read_csv("权重文件.csv") # count_df = pd.read_csv("数量文件.csv") # 合并两个表 merged_df = pd.merge(weight_df, count_df, on="SECTION")
步骤3:按SECTION分组生成样本
对每个SECTION分组,根据权重比例和需求数量随机抽取CODE:
import numpy as np # 定义生成单组样本的函数 def generate_samples(group): codes = group["CODE"] weights = group["Final_Per"] num_samples = group["NUMBER"].iloc[0] # 每个SECTION的样本数唯一 # 按权重随机抽取,允许重复抽取以满足数量需求 samples = pd.Series( np.random.choice(codes, size=num_samples, p=weights, replace=True), name="SAMPLED_CODE" ) # 添加SECTION标识列 samples = samples.to_frame().assign(SECTION=group["SECTION"].iloc[0]) return samples # 分组应用函数生成所有样本 result = merged_df.groupby("SECTION").apply(generate_samples).reset_index(drop=True)
步骤4:查看结果
运行后result就是最终的样本表,比如B1对应的14个样本会按5%/65%/30%的比例包含800、801、802:
print(result[result["SECTION"] == "B1"])
注意事项
- 确保每个SECTION下的
Final_Per之和为1,否则np.random.choice会报错。如果有微小误差,可先做归一化:group["Final_Per"] = group["Final_Per"] / group["Final_Per"].sum() - CODE为字符串类型时,代码无需修改,同样适用。
内容的提问来源于stack exchange,提问作者Connor Garrett
相关产品推荐
相关产品推荐

