如何基于另一DataFrame将Pandas列的类别映射为对应值?
解决方案:将WOE权重映射到分类DataFrame
这是WOE编码(Weight of Evidence)场景里很典型的需求,我给你两种实用的Pandas实现方案,都能完美得到你想要的结果:
第一步:先模拟你的数据(方便测试)
首先我们先把你描述的两个DataFrame用代码创建出来,这样你可以直接运行验证:
import pandas as pd # 原始分类DataFrame df_categories = pd.DataFrame({ 'var1': ['A', 'B', 'C'], 'var2': ['x', 'y', 'z'] }) # 存储WOE权重的DataFrame df_woe_weights = pd.DataFrame({ 'var_name': ['var1', 'var1', 'var1', 'var2', 'var2', 'var2'], 'category': ['A', 'B', 'C', 'x', 'y', 'z'], 'value': [0.2, 0.3, 0.4, 0.8, 0.9, 1] })
方案一:逐列使用merge匹配(适合列数少的场景)
这种方法逻辑直观,逐列将分类值和对应的WOE权重关联:
# 先处理var1,将原DataFrame的var1和WOE表中var1的记录匹配 df_result = df_categories.merge( df_woe_weights[df_woe_weights['var_name'] == 'var1'], left_on='var1', right_on='category', how='left' ).rename(columns={'value': 'var1'})[['var1']] # 再处理var2,同样匹配并合并到结果中 df_result = df_result.merge( df_woe_weights[df_woe_weights['var_name'] == 'var2'], left_index=True, right_on='category', left_on=df_categories['var2'], how='left' ).rename(columns={'value': 'var2'})[['var1', 'var2']]
说明:使用how='left'可以保证原DataFrame的行顺序完全保留,同时如果有匹配不到的分类值,会填充NaN,方便后续排查数据问题。
方案二:构建WOE字典后批量map(适合列数多的场景)
这种方法更高效且扩展性强,先把每个变量的WOE规则做成字典,再批量替换:
# 按变量名分组,构建{变量名: {分类: WOE值}}的嵌套字典 woe_mapping = {} for var_name in df_woe_weights['var_name'].unique(): # 提取当前变量的所有分类和对应WOE值,转成字典 var_woe = df_woe_weights[df_woe_weights['var_name'] == var_name] woe_mapping[var_name] = var_woe.set_index('category')['value'].to_dict() # 对原DataFrame的每一列,用对应的WOE字典映射替换 df_result = df_categories.apply(lambda column: column.map(woe_mapping[column.name]))
说明:这个方案不需要针对每一列写重复代码,就算后续新增更多分类列,只要WOE表的格式不变,代码不用修改。如果遇到原DataFrame中有WOE字典里没有的分类,map会返回NaN,你可以用fillna()设置默认值,或者提前清理数据。
最终结果
两种方案运行后都会得到你想要的结果:
| var1 | var2 |
|---|---|
| 0.2 | 0.8 |
| 0.3 | 0.9 |
| 0.4 | 1.0 |
内容的提问来源于stack exchange,提问作者Bruno Pinheiro
相关产品推荐
相关产品推荐

