如何基于标签列对pandas DataFrame做下采样,实现每类样本数量一致
实现方法
你需要对数据集做随机下采样,将每个类别的样本量统一对齐到所有类别的最小样本数即可,具体实现步骤如下:
步骤1:计算所有类别最小样本数
首先统计每个标签的样本量,取最小值作为统一采样的数量:
import pandas as pd # 假设你的原始数据集命名为 df min_sample_count = df["label"].value_counts().min()
这里计算出来的min_sample_count就是你给出的615。
步骤2:按类别分组采样
使用groupby对标签分组,对每个分组随机抽取对应数量的样本:
# 随机下采样,设置random_state固定随机种子可复现结果 balanced_df = df.groupby("label", group_keys=False)\ .apply(lambda group: group.sample(n=min_sample_count, random_state=42))\ .reset_index(drop=True)
参数说明:
group_keys=False:避免分组后额外生成label层级的索引random_state=42:固定随机种子,每次运行得到的采样结果一致,可根据需求修改或删除reset_index(drop=True):重置最终数据集的索引,删除原始数据集的行号
可选:非随机按顺序采样
如果你不需要随机采样,只需要取每个类别最前面的N条数据,可以把sample方法替换为head:
balanced_df = df.groupby("label", group_keys=False)\ .apply(lambda group: group.head(min_sample_count))\ .reset_index(drop=True)
结果验证
运行以下代码可以验证采样结果是否符合要求:
# 统计每个类别的样本量,应该全部等于615 print(balanced_df["label"].value_counts()) # 查看总长度,应该等于 8*615 = 4920 print(len(balanced_df))
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

