Pandas实现分类值替换为label=1对应频率的简洁方法
分类值替换为对应类别正样本占比的简洁实现
问题说明
现有如下测试DataFrame:
data = [['a1','b1',0], ['a2','b3',0], ['a1','b2',1], ['a1','b1',1], ['a2','b3',0]] df = pd.DataFrame(data=data, columns = ['A','B','label'])
除label列外其余列均为字符串类型分类值,需要将各分类值替换为该类别下label=1的占比,计算规则示例:
n(a1) = count(A == 'a1' & label = 1)/count(A == 'a1')
原有逐列遍历构建映射字典、再调用replace替换的写法逻辑冗余,还存在跨列同值分类映射互相覆盖的隐患,可使用pandas内置的分组统计方法简化实现。
实现代码
利用0/1列的均值等于正样本占比的特性,配合groupby+map实现,无需手动遍历每个分类值:
# 遍历所有非label列 for col in df.columns.drop('label'): # 分组计算每个分类对应的正样本占比,直接生成映射 pos_rate = df.groupby(col)['label'].mean() # 替换原列值 df[col] = df[col].map(pos_rate)
运行后得到的结果如下:
A B label 0 0.666667 0.500000 0 1 0.000000 0.000000 0 2 0.666667 1.000000 1 3 0.666667 0.500000 1 4 0.000000 0.000000 0
实现说明
- 由于
label列取值仅为0和1,分组后对label求均值,结果恰好等于组内正样本数/组内总样本数,无需单独统计总样本量和正样本量。 - 按列单独生成映射表,避免了原写法中全局字典被跨列同名分类覆盖的问题,鲁棒性更强。
- pandas原生
groupby实现的运行效率比手动逐值遍历更高,代码逻辑也更简洁易维护。
内容的提问来源于stack exchange,提问作者user6703592
相关产品推荐
相关产品推荐

