You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas基于两列子串匹配为df1添加Address列?

问题描述

现有两个Pandas DataFrame:

DataFrame df1

Rep
0   ec21b_AI_154OH
1   m2010_AI_066UW
2   20wh1_DS_416FC

DataFrame df2

Address     FirstPart   SecondPart
0   address13   m2010       066UW
1   address22   2020e       999GV
2   address26   2020c       513DT
3   address35   evd18       874GO
4   address36   ep21b       986CG
5   address493  20wh1       416FC
6   address628  ec21b       154OH

需求是在df1中添加Address列,最终结果如下:

Rep             Address
0   ec21b_AI_154OH  address628
1   m2010_AI_066UW  address13
2   20wh1_DS_416FC  address493

目前已通过循环实现该需求,代码如下:

for First, Second, Add in zip(list(df2['FirstPart']),list(df2['SecondPart']),list(df2['Address'])):
    condition = df1['Rep'].str.contains(First) & df1['Rep'].str.contains(Second)
    df1.loc[condition,"Address"] = Add

注:无需以_作为分隔符,Rep字段可能存在其他分隔符。现询问是否有更优的实现方式?

更优实现方式

循环遍历的方式在数据量较大时效率较低,推荐使用Pandas的矢量化操作来实现,以下是几种可行方案:

方案一:正则匹配结合apply关联

先为df2构造包含双条件的正则匹配键,再通过apply完成关联:

import pandas as pd

# 生成同时包含FirstPart和SecondPart的正则表达式
df2['match_pattern'] = df2.apply(lambda x: f'(?=.*{x["FirstPart"]})(?=.*{x["SecondPart"]})', axis=1)

# 为每个Rep匹配对应的Address
df1['Address'] = df1['Rep'].apply(
    lambda rep: df2.loc[df2['match_pattern'].str.match(rep), 'Address'].iloc[0] 
    if not df2.loc[df2['match_pattern'].str.match(rep), 'Address'].empty 
    else None
)

方案二:利用numpy广播批量判断匹配

借助numpy的广播机制一次性完成所有匹配判断,避免逐行循环:

import pandas as pd
import numpy as np

# 将数据转为numpy数组,方便广播运算
rep_arr = df1['Rep'].values[:, np.newaxis]
first_arr = df2['FirstPart'].values
second_arr = df2['SecondPart'].values

# 批量判断每个Rep是否同时包含对应的FirstPart和SecondPart
match_mask = np.logical_and(
    np.char.find(rep_arr, first_arr) != -1,
    np.char.find(rep_arr, second_arr) != -1
)

# 根据匹配结果映射对应的Address
df1['Address'] = df2['Address'].values[match_mask.argmax(axis=1)]

方案三:直接通过in关键字做包含判断

这是更简洁的矢量化写法,直接判断子串是否存在:

df1['Address'] = df1['Rep'].apply(
    lambda x: df2.loc[
        (df2['FirstPart'].apply(lambda fp: fp in x)) & 
        (df2['SecondPart'].apply(lambda sp: sp in x)), 
        'Address'
    ].iloc[0]
)

这些方案都利用了Pandas和numpy的矢量化特性,相比显式循环,在数据量较大时能显著提升运行效率。

内容的提问来源于stack exchange,提问作者TRK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:01:19