如何基于字符串部分匹配实现两个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的结果和预期完全一致:
| City | Val | Geo |
|---|---|---|
| San Francisco, CA | 1 | geo1 |
| Oakland, CA | 2 | geo1 |
方法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
相关产品推荐
相关产品推荐

