如何基于标签出现次数删除数据集行(处理多标签重叠)
多标签数据集样本平衡处理方案
数据集结构
我有一个大型数据集,结构如下:
text label1 label2 label3 labelN any string 1 0 1 1 oasjdaskd 1 1 0 1 fghfghfh 1 0 0 0
其中label1至labelN可为任意名称,比如color、size等。
上述示例中:label1出现3次,label2出现1次,label3出现1次,labelN出现2次。
需求说明
设置threshold=500,若某标签出现次数为600次,则随机删除100条标记该标签为1的文本行;出现次数少于500的标签不做处理。
核心问题:同一文本(行)可能被多个标签标记为1,删除一行会同时减少多个标签的计数。
补充示例数据
print(df) text label1 label2 label3 labelN 0 any string1 0 0 1 1 1 any string 1 0 1 0 2 oasjdaskd 1 1 1 1 3 fghfghfh 1 0 1 1
阈值设置为threshold=2
实现思路与代码
核心思路
- 先统计每个标签的当前出现次数,筛选出计数超过阈值的标签
- 对每个需削减的标签,计算需要删除的行数(当前计数 - 阈值)
- 从标记该标签为1且未被标记删除的行中,随机选取对应数量的行标记为待删除
- 最后统一删除所有标记行,避免重复处理同一行
代码实现
import pandas as pd import numpy as np # 加载示例数据集(实际使用时替换为你的数据加载逻辑) data = { 'text': ['any string1', 'any string', 'oasjdaskd', 'fghfghfh'], 'label1': [0, 1, 1, 1], 'label2': [0, 0, 1, 0], 'label3': [1, 1, 1, 1], 'labelN': [1, 0, 1, 1] } df = pd.DataFrame(data) threshold = 2 # 初始化待删除标记列 df['to_drop'] = False # 筛选所有标签列(可根据实际标签命名规则调整) label_cols = [col for col in df.columns if col.startswith('label')] # 统计各标签当前出现次数,按降序排列 label_counts = df[label_cols].sum().sort_values(ascending=False) # 逐个处理超阈值的标签 for label, count in label_counts.items(): if count <= threshold: continue # 计算需要删除的行数 need_drop = count - threshold # 获取候选行:当前标签为1且未被标记删除的行 candidate_rows = df[(df[label] == 1) & (~df['to_drop'])] # 随机选取待删除行 if len(candidate_rows) <= need_drop: # 候选行不足时直接标记所有 df.loc[candidate_rows.index, 'to_drop'] = True else: drop_indices = np.random.choice(candidate_rows.index, size=need_drop, replace=False) df.loc[drop_indices, 'to_drop'] = True # 生成平衡后的数据集 balanced_df = df[~df['to_drop']].drop('to_drop', axis=1) # 输出结果 print("平衡后的数据集:") print(balanced_df) print("\n平衡后各标签计数:") print(balanced_df[label_cols].sum())
代码说明
- 新增
to_drop列标记待删除行,避免同一行被多次选中删除 - 按标签计数从高到低处理,优先解决最失衡的标签
- 每次仅从未被标记的行中选取样本,保证处理逻辑的准确性
- 统一删除标记行,提升大型数据集处理效率
内容的提问来源于stack exchange,提问作者Katty_one
相关产品推荐
相关产品推荐

