Pandas如何跨DataFrame条件查找值 无迭代填充目标列
实现方案
完全可以不使用逐行遍历的方式实现需求,基于pandas的向量化操作即可完成,运行效率远高于逐行循环,以下是两种常用实现方式:
方式1:按类型掩码+映射匹配(逻辑直观,适合类型少的场景)
核心思路是提前构建各匹配场景的键值映射,通过布尔掩码筛选对应类型的行,批量完成匹配填充:
import pandas as pd # -------------------------- # 1. 预构建各类型对应的查找映射:以匹配列为索引,待填充的description为值 # -------------------------- # Type=ID时,匹配Lookup1的ID列 map_id = Lookup1.set_index('ID')['description'] # Type=CI时,匹配Lookup1的CI列 map_ci = Lookup1.set_index('CI')['description'] # Type=CC时,匹配Lookup2的CC列 map_cc = Lookup2.set_index('CC')['description'] # -------------------------- # 2. 初始化目标列,先填充else分支的默认值 # -------------------------- # 伪代码中else分支取Code2列,如果需要取示例中空Type行的Description值,替换为source_df['Description']即可 source_df['col_new'] = source_df['Code2'] # -------------------------- # 3. 按类型批量匹配填充,全程无逐行循环 # -------------------------- # 填充ID类型 mask_id = source_df['Type'] == 'ID' source_df.loc[mask_id, 'col_new'] = source_df.loc[mask_id, 'Code'].map(map_id) # 填充CI类型 mask_ci = source_df['Type'] == 'CI' source_df.loc[mask_ci, 'col_new'] = source_df.loc[mask_ci, 'Code'].map(map_ci) # 填充CC类型 mask_cc = source_df['Type'] == 'CC' source_df.loc[mask_cc, 'col_new'] = source_df.loc[mask_cc, 'Code'].map(map_cc)
- 注意:匹配前请确保
Code列和查找表对应匹配列的数据类型一致(比如同为字符串/同为数值),否则会出现匹配失败的问题。如果需要处理匹配不到的空值,可以在map()后追加.fillna(你要的默认值)。
方式2:统一查找表+双字段关联(扩展性好,适合类型多的场景)
如果后续需要新增更多匹配类型,可以先把所有查找规则整理成统一结构的总查找表,通过Type+Code两个字段一次性关联完成匹配,不需要反复写掩码判断:
# -------------------------- # 1. 将所有查找表转换为统一结构:包含Type、Code(匹配值)、description(待填充值)三列 # -------------------------- lookup_id = Lookup1[['ID', 'description']].rename(columns={'ID':'Code'}).assign(Type='ID') lookup_ci = Lookup1[['CI', 'description']].rename(columns={'CI':'Code'}).assign(Type='CI') lookup_cc = Lookup2[['CC', 'description']].rename(columns={'CC':'Code'}).assign(Type='CC') # 合并为总查找表 total_lookup = pd.concat([lookup_id, lookup_ci, lookup_cc], ignore_index=True) # -------------------------- # 2. 一次性关联匹配 # -------------------------- source_df = source_df.merge( total_lookup, on=['Type', 'Code'], how='left' ).rename(columns={'description':'col_new'}) # -------------------------- # 3. 填充未匹配到的行(对应else分支的默认值) # -------------------------- source_df['col_new'] = source_df['col_new'].fillna(source_df['Code2'])
两种方式都是pandas底层优化过的向量化实现,性能比逐行for循环高1~2个数量级,数据量越大优势越明显。
内容的提问来源于stack exchange,提问作者fr0do007
相关产品推荐
相关产品推荐

