You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas的np.where语句中用字典实现列映射

基于映射字典实现DataFrame按条件取列值的方法

问题背景

给定以下DataFrame:

import pandas as pd
foo = pd.DataFrame({'id': [1,1,1,2,2,2],
                    'time': [1,2,3,1,2,3],
             'col_id': ['ffp','ffp','ffp', 'hie', 'hie', 'ttt'],
             'col_a': [1,2,3,4,5,6],
             'col_b': [-1,-2,-3,-4,-5,-6],
                'col_c': [10,20,30,40,50,60]})

需求是创建新列col,根据col_id的取值,分别从col_a、col_b或col_c中提取对应值。原实现采用嵌套np.where,但当列数较多时代码冗余,希望通过以下映射字典简化实现:

dict_cols_matching = {"ffp" : "col_a", "hie": "col_b", "ttt": "col_c"}

实现方案

方案1:使用lookup方法(简洁直观)

lookup可直接根据行索引和目标列名的匹配关系提取值,结合字典映射快速实现:

foo['col'] = foo.lookup(foo.index, foo['col_id'].map(dict_cols_matching))

注意:lookup在pandas 1.2.0及以上版本被标记为弃用,但当前仍可正常使用;若需长期兼容性,建议选择其他方案。

方案2:apply逐行映射(逻辑清晰)

通过apply遍历每行,根据col_id从字典中获取目标列名,再提取对应值:

foo['col'] = foo.apply(lambda row: row[dict_cols_matching[row['col_id']]], axis=1)

该方法逻辑易懂,适合映射规则复杂的场景,但在大数据集下效率略低于向量化方法。

方案3:向量化实现(性能最优)

利用numpy的索引机制实现完全向量化操作,处理大规模数据时效率最高:

# 建立列名到DataFrame列索引的映射
col_position = {col: idx for idx, col in enumerate(foo.columns)}
# 将col_id转换为目标列的索引位置
target_positions = foo['col_id'].map(dict_cols_matching).map(col_position)
# 提取对应位置的值
foo['col'] = foo.values[foo.index, target_positions]

方案4:melt+合并(扩展性强)

如果后续需要频繁调整映射规则,可先将数据转为长格式再匹配:

# 将需要映射的列转为长格式
melted_df = foo.melt(
    id_vars=['id', 'time', 'col_id'],
    value_vars=['col_a', 'col_b', 'col_c'],
    var_name='source_col',
    value_name='col'
)
# 生成反向映射(列名对应col_id值)
reverse_map = {v: k for k, v in dict_cols_matching.items()}
melted_df['match_id'] = melted_df['source_col'].map(reverse_map)
# 匹配后合并回原数据
foo = foo.merge(
    melted_df[melted_df['col_id'] == melted_df['match_id']][['id', 'time', 'col']],
    on=['id', 'time'],
    how='left'
)

该方案代码稍长,但扩展性好,便于后续修改映射关系。

内容的提问来源于stack exchange,提问作者quant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 01:01:51