基于DataFrame2条件从DataFrame1提取值并填充(Pandas Python续篇)
解决方案:基于多列匹配提取并填充DataFrame值
首先,我注意到你的df2中P1列是字符串类型(比如'0'),而df1的P1是整数类型,这会导致直接匹配失败,所以第一步需要先统一数据类型,再进行匹配提取。
下面提供两种高效的实现方法,都能得到你期望的结果:
方法一:使用pd.merge(最直观的多列匹配方式)
merge是pandas中专门用于合并DataFrame的工具,非常适合这种基于多键匹配的场景:
import pandas as pd # 初始化你的df1 data1 = {'HJ':[5,11,21,99,15], 'P1':[51,66,7,0,11] ,'P2':[ 33,45,55 ,76 ,42]} df1 = pd.DataFrame(data1) # 初始化你的df2 data2 = {'HJ':[99,11,5,21,11], 'P1':['0','66','51','7','66']} df2 = pd.DataFrame(data2) # 第一步:统一P1列的数据类型(将df2的P1转为整数) df2['P1'] = df2['P1'].astype(int) # 第二步:基于HJ和P1两列匹配,合并df1的P2列到df2 df2 = df2.merge(df1[['HJ', 'P1', 'P2']], on=['HJ', 'P1'], how='left').rename(columns={'P2': 'Ans'}) print(df2)
运行后输出的结果就是你期望的:
HJ P1 Ans 0 99 0 76 1 11 66 45 2 5 51 33 3 21 7 55 4 11 66 45
方法二:使用set_index + map(更灵活的映射方式)
如果你希望更灵活地处理映射关系,可以把df1的HJ和P1设置为复合索引,然后用map来匹配取值:
import pandas as pd # 初始化数据(同上) data1 = {'HJ':[5,11,21,99,15], 'P1':[51,66,7,0,11] ,'P2':[ 33,45,55 ,76 ,42]} df1 = pd.DataFrame(data1) data2 = {'HJ':[99,11,5,21,11], 'P1':['0','66','51','7','66']} df2 = pd.DataFrame(data2) # 统一数据类型 df2['P1'] = df2['P1'].astype(int) # 创建复合索引的映射系列 p2_map = df1.set_index(['HJ', 'P1'])['P2'] # 给df2添加Ans列,通过映射取值 df2['Ans'] = df2.apply(lambda row: p2_map[(row['HJ'], row['P1'])], axis=1) print(df2)
这个方法同样会得到和上面一致的结果,适合需要自定义映射逻辑的场景。
关键注意点
- 数据类型统一:一定要确保匹配的列(这里是
HJ和P1)在两个DataFrame中的类型一致,否则会出现匹配不到的情况。 - 匹配方式:
merge的how='left'参数保证了df2的所有行都会被保留,即使没有匹配到(这种情况会显示NaN,但你的示例中所有行都能匹配到)。
内容的提问来源于stack exchange,提问作者ManOnTheMoon
相关产品推荐
相关产品推荐

