如何使用Pandas对不等长ragged序列数据过采样实现类别均衡
Pandas实现不等长序列组的类别均衡过采样
核心实现逻辑:过采样最小单位为完整id对应的特征组,不拆分单条特征行,对少数类id做有放回采样后分配全新唯一id,拼接回原数据集即可。
完整实现代码
import pandas as pd import random # 输入原始数据 x = pd.DataFrame({'id':[1,1,1,2,2,3,3,3,3,4,5,6,6],'f1':[11,11,11,22,22,33,33,33,33,44,55,66,66]}) y = pd.DataFrame({'id':[1,2,3,4,5,6],'target':[1,0,1,0,0,0]}) # 配置参数 target_per_class = 4 # 目标每个类别的样本量 random.seed(42) # 固定随机种子保证结果可复现 # 1. 计算需要补充的少数类样本量 minority_ids = y[y['target'] == 1]['id'].tolist() need_sample_num = target_per_class - len(minority_ids) # 2. 有放回采样待复制的少数类id sampled_old_ids = random.choices(minority_ids, k=need_sample_num) # 3. 生成不重复的新id(从原有最大id+1开始递增) max_exist_id = max(x['id'].max(), y['id'].max()) new_ids = [max_exist_id + 1 + i for i in range(need_sample_num)] # 4. 生成新特征集片段 new_x_parts = [] for old_id, new_id in zip(sampled_old_ids, new_ids): # 完整复制原id对应的所有特征行,替换为新id group_df = x[x['id'] == old_id].copy() group_df['id'] = new_id new_x_parts.append(group_df) new_x = pd.concat(new_x_parts, ignore_index=True) # 5. 生成新标签集片段 new_y = pd.DataFrame({'id': new_ids, 'target': [1]*need_sample_num}) # 6. 合并得到最终数据集 final_x = pd.concat([x, new_x], ignore_index=True) final_y = pd.concat([y, new_y], ignore_index=True)
结果验证
运行以下代码可验证输出是否符合要求:
# 验证标签分布 print("最终标签类别计数:") print(final_y['target'].value_counts()) # 输出0和1的计数均为4 # 验证各组特征长度 print("\n各id对应的特征行数:") print(final_x.groupby('id').size()) # 新id7、8的行数和对应原id1、3的行数完全一致
内容的提问来源于stack exchange,提问作者Shlomi Schwartz
相关产品推荐
相关产品推荐

