如何在Pandas中基于source和category两列映射生成contract_type列?
解决Pandas中双列映射优先替换的问题
我来帮你搞定这个需求!核心逻辑就是先基于source列用source_map生成默认值,再检查category列是否包含mobis_map的键,如果包含就优先替换成对应的值。下面是具体的实现步骤和代码示例:
步骤1:准备数据和映射字典
首先我们先还原示例中的数据和映射关系:
import pandas as pd import numpy as np # 示例原始数据 data = { 'source': ['ALLIAN', 'ALLSB', '00CORP', '00CORP'], 'category': ['ALL', 'ASB', '100 01', '847 1'] } df = pd.DataFrame(data) # 定义两个映射字典(根据示例补充完整) source_map = { 'ALLIAN': 'ALLIAN', 'ALLSB': 'ALLSB', '00CORP': '00CORP' } mobis_map = { '847': 'MOBIS' # 示例中category包含847时映射为MOBIS }
步骤2:生成默认的contract_type列
先基于source列,用map()方法快速生成默认的contract_type值:
df['contract_type'] = df['source'].map(source_map)
步骤3:实现优先替换逻辑
这里提供两种方案,你可以根据数据集大小选择:
方案一:直观的逐行判断(适合小数据集)
写一个自定义函数,用apply()逐行检查category是否包含mobis_map的键,匹配到就返回对应值,否则保留默认值:
def get_final_contract_type(row): # 遍历mobis_map的所有键,检查是否在当前行的category中 for key, value in mobis_map.items(): if key in row['category']: return value # 没有匹配的键时返回默认值 return row['contract_type'] df['contract_type'] = df.apply(get_final_contract_type, axis=1)
方案二:高效的向量式操作(适合大数据集)
避免逐行循环,用Pandas的字符串方法和布尔索引实现,性能更优:
# 构建匹配掩码:判断category是否包含任意mobis_map的键 mobis_keys = '|'.join(mobis_map.keys()) mask = df['category'].str.contains(mobis_keys) # 对匹配到的行,提取对应的键并映射为mobis_map的值,替换原有的contract_type df.loc[mask, 'contract_type'] = df.loc[mask, 'category'].str.extract(f"({mobis_keys})")[0].map(mobis_map)
最终结果
运行完上面的代码后,查看数据框:
print(df)
输出结果完全符合你的示例:
source category contract_type 0 ALLIAN ALL ALLIAN 1 ALLSB ASB ALLSB 2 00CORP 100 01 00CORP 3 00CORP 847 1 MOBIS
如果你的mobis_map有多个键,或者需要处理更复杂的匹配规则,只需要调整映射字典和匹配逻辑即可~
内容的提问来源于stack exchange,提问作者spitfiredd
相关产品推荐
相关产品推荐

