如何用Pandas DataFrame快速平衡标签类别数量?
解决Pandas DataFrame类别标签失衡的简便方法
当遇到标签类别占比失衡(比如示例中bike:car=7:3)时,完全不需要手动逐行处理,用以下几种方法可以快速实现类别数量一致:
1. 欠采样(减少多类别样本数量)
直接将数量多的类别随机采样到和最少类别相同的数量,适合数据集本身较大的场景:
import pandas as pd # 假设数据集为df,标签列名为'label' # 获取所有类别中最少的样本数 min_sample_num = df['label'].value_counts().min() # 按标签分组后,每个组采样到min_sample_num条数据 balanced_df = df.groupby('label').apply(lambda group: group.sample(min_sample_num)).reset_index(drop=True)
2. 过采样(扩充少类别样本数量)
如果数据集不大,可以把数量少的类别样本扩充到和最多类别相同的数量,分两种方式:
简单重复采样(快速但可能过拟合)
直接重复少类别样本:
max_sample_num = df['label'].value_counts().max() balanced_df = df.groupby('label').apply(lambda group: group.sample(max_sample_num, replace=True)).reset_index(drop=True)
智能合成采样(生成新样本,更合理)
用SMOTE算法生成新的合成样本,需要先安装imblearn库:
from imblearn.over_sampling import SMOTE import pandas as pd # 分离特征列和标签列 X = df.drop('label', axis=1) y = df['label'] # 初始化SMOTE,随机种子保证结果可复现 smote = SMOTE(random_state=42) # 生成平衡后的特征和标签 X_balanced, y_balanced = smote.fit_resample(X, y) # 重新组合成DataFrame balanced_df = pd.concat([pd.DataFrame(X_balanced, columns=X.columns), pd.Series(y_balanced, name='label')], axis=1)
方法选择建议
- 数据量充足时优先用欠采样,避免引入重复或合成数据带来的偏差
- 数据量较小时用SMOTE过采样,比简单重复更能避免模型过拟合
内容的提问来源于stack exchange,提问作者Yang
相关产品推荐
相关产品推荐

