Pandas多列匹配查询:匹配df2任意列返回对应df2['m']值
问题
示例数据
import pandas as pd df1 = pd.DataFrame({ 'a': [1, 6, 3, 9], 'b': ['A', 'B', 'C', 'D'], 'c': [10, 20, 30, 40], 'd': [100, 200, 300, 400] }) df2 = pd.DataFrame({ 'm': [1, 5, 3, 7], 'n': [2, 6, 8, 4], 'o': [9, 10, 11, 12] })
需求
df1['a']的值可能出现在df2的任意列中,无论匹配到df2的哪一列,都返回对应的df2['m']值;若未匹配到任何列,则保留df1['a']的原值。
原尝试方案
尝试通过melt处理df2后与df1合并,但无法检测df2['m']列中的匹配项,导致部分结果为NaN。后续通过填充NaN值解决,但方案冗余:
df2_melted = df2.melt(id_vars=['m'], value_vars=['n', 'o']) merged_df = df1.merge(df2_melted, left_on='a', right_on='value', how='left') df1['e'] = merged_df['m'] df1['e'] = (df1['e'].fillna(df1['a'])).astype(int)
更简洁高效的解决方案
方法1:构建全局映射字典(逻辑直观)
先遍历df2生成所有值到对应m的映射关系,再直接用map匹配:
# 构建值到m的映射 mapping = {} for idx, row in df2.iterrows(): m_val = row['m'] # 将当前行的所有值(包括m列本身)都映射到对应的m值 for val in row.values: mapping[val] = m_val # 生成目标列:匹配映射,无匹配则保留原值 df1['e'] = df1['a'].map(mapping).fillna(df1['a']).astype(int)
方法2:向量化melt操作(大数据场景更高效)
通过临时复制m列,让其能参与melt,避免遗漏匹配:
# 复制m列作为临时列,使其可纳入value_vars df2_temp = df2.assign(m_temp=df2['m']) # 执行melt,包含所有列的匹配值 df2_melted = df2_temp.melt(id_vars=['m'], value_vars=['m_temp', 'n', 'o'], value_name='match_val') # 合并后直接提取m值,无匹配则填充原a列值 merged_df = df1.merge(df2_melted[['m', 'match_val']], left_on='a', right_on='match_val', how='left') df1['e'] = merged_df['m'].fillna(df1['a']).astype(int)
两种方法均能满足需求,方法1适合小数据场景,逻辑易懂;方法2用向量化操作,大数据下性能更优。
内容的提问来源于stack exchange,提问作者RatDon
相关产品推荐
相关产品推荐

