如何用Python实现VLOOKUP?DataFrame同名匹配遇全NaN问题求助
Pandas实现类似VLOOKUP的名称匹配问题
问题场景
现有两个DataFrame df1 和 df2,需要基于name列实现类似Excel中VLOOKUP的功能,找出在两个表中匹配的名称。示例数据如下:
import pandas as pd import numpy as np df1 = pd.DataFrame({ 'name': ['A', 'B', 'C', 'D'], 'val1': [5, 6, 7, 8], 'val2': [1, 2, 3, 4], }) df2 = pd.DataFrame({ 'name': ['B', 'D', 'E', 'F'], 'abc': [15, 16, 17, 18], 'def': [11, 21, 31, 41], })
期望输出:
name val1 val2 matched_name A 5 1 NaN B 6 2 B C 7 3 NaN D 8 4 D
尝试执行以下代码后,matched_name列全为NaN:
df1['matched_name'] = df1['name'].map(df2['name'])
原因分析
Series.map()方法如果传入另一个Series,会以传入Series的索引作为匹配键,而不是Series的值。 原代码中用df2['name']作为参数,实际是用df2的索引(0、1、2、3)去匹配df1['name']的值(A、B、C、D),完全没有匹配项,所以全部返回NaN。
解决方法
方法1:用isin()结合where()
先判断df1['name']是否存在于df2['name']的取值中,保留匹配的名称,不匹配的设为NaN:
df1['matched_name'] = df1['name'].where(df1['name'].isin(df2['name']))
方法2:将df2['name']转为自映射字典
利用map()接收字典的特性,构建键和值相同的字典,实现匹配:
name_map = dict(zip(df2['name'], df2['name'])) df1['matched_name'] = df1['name'].map(name_map)
方法3:用merge()实现关联(适合扩展更多列)
如果后续需要关联df2中的其他列,这种方式更灵活:
# 仅保留df2的name列进行左连接 df_result = df1.merge(df2[['name']], on='name', how='left', suffixes=('', '_matched')) # 重命名列名符合需求 df_result.rename(columns={'name_matched': 'matched_name'}, inplace=True)
内容的提问来源于stack exchange,提问作者Akilesh
相关产品推荐
相关产品推荐

