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

如何基于字符串部分匹配实现两个pandas DataFrame的左外连接

实现方案

核心逻辑是对df1每行的城市名,判断是否是df2城市字段的子串,匹配成功则提取对应Geo值,完全保留df1的所有行(左外连接逻辑)。

方法1:逐行匹配(适合小数据量)

import pandas as pd

# 示例数据初始化
df1 = pd.DataFrame({
    'City': ['San Francisco, CA', 'Oakland, CA'],
    'Val': [1, 2]
})

df2 = pd.DataFrame({
    'City': ['San Francisco-Oakland, CA', 'Salinas, CA'],
    'Geo': ['geo1', 'geo2']
})

# 定义匹配规则:提取城市名前缀判断是否被df2的城市字段包含
def get_matched_geo(city):
    # 去掉州后缀,提取纯城市名
    city_prefix = city.split(',')[0].strip()
    matched = df2[df2['City'].str.contains(city_prefix)]
    return matched['Geo'].iloc[0] if not matched.empty else None

# 新增Geo字段
df1['Geo'] = df1['City'].apply(get_matched_geo)

运行后df1的结果和预期完全一致:

CityValGeo
San Francisco, CA1geo1
Oakland, CA2geo1

方法2:交叉连接过滤(适合中等数据量)

如果数据量稍大,逐行匹配多次查询df2效率较低,可以先构造临时关联键做交叉连接,再统一过滤匹配项:

df1['tmp_join_key'] = 1
df2['tmp_join_key'] = 1

# 交叉连接
cross_join_df = df1.merge(df2, on='tmp_join_key', suffixes=('', '_right'))
# 过滤符合子串匹配规则的行
cross_join_df = cross_join_df[cross_join_df.apply(lambda x: x['City'].split(',')[0].strip() in x['City_right'], axis=1)]
# 提取需要的字段得到最终结果
result = cross_join_df[['City', 'Val', 'Geo']].reset_index(drop=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:21:04