基于三类条件的部分字符串匹配实现Pandas数据集左连接
解决左连接的动态匹配需求
我来帮你搞定这个左连接的匹配逻辑,分两步拆解会更清晰:
第一步:格式化CodeA为标准4位编码
因为CodeA可能是2、3或4位,得先补尾随零统一成4位格式,这里给你两种常用场景的实现方式:
SQL 实现
把CodeA转成字符串后补零(适配多数关系型数据库):
SELECT *, RIGHT('0000' + CAST(CodeA AS VARCHAR(4)), 4) AS FormattedCodeA FROM DatasetA
注:如果是MySQL可以用LPAD(CodeA, 4, '0'),逻辑是一样的
Pandas 实现
用字符串填充方法直接补零:
import pandas as pd df_a['FormattedCodeA'] = df_a['CodeA'].astype(str).str.zfill(4)
第二步:实现动态左连接匹配
核心是根据FormattedCodeA的后缀情况,匹配对应的4位CodeB,直接上可运行的代码:
SQL 左连接写法
在ON子句里直接写条件判断,逻辑一目了然:
SELECT a.*, b.* FROM ( SELECT *, RIGHT('0000' + CAST(CodeA AS VARCHAR(4)), 4) AS FormattedCodeA FROM DatasetA ) a LEFT JOIN DatasetB b ON -- 情况1:最后两位是00,匹配前两位相同的CodeB (RIGHT(a.FormattedCodeA, 2) = '00' AND LEFT(b.CodeB, 2) = LEFT(a.FormattedCodeA, 2)) OR -- 情况2:仅最后一位是0(倒数第二位非0),匹配前三位相同的CodeB (RIGHT(a.FormattedCodeA, 1) = '0' AND RIGHT(a.FormattedCodeA, 2) != '00' AND LEFT(b.CodeB, 3) = LEFT(a.FormattedCodeA, 3)) OR -- 情况3:完整四位非零尾,完全匹配 (RIGHT(a.FormattedCodeA, 1) != '0' AND b.CodeB = a.FormattedCodeA)
Pandas 左连接写法
先给数据集标记匹配类型,再分情况合并:
# 给DatasetB添加不同长度的前缀匹配键 df_b['Prefix2'] = df_b['CodeB'].str[:2] df_b['Prefix3'] = df_b['CodeB'].str[:3] df_b['FullCode'] = df_b['CodeB'] # 给DatasetA标记匹配类型和对应键 def get_match_rule(row): code = row['FormattedCodeA'] if code.endswith('00'): return ('prefix2', code[:2]) elif code.endswith('0'): return ('prefix3', code[:3]) else: return ('full', code) df_a[['match_type', 'match_key']] = df_a.apply(get_match_rule, axis=1, result_type='expand') # 分情况匹配后合并结果 match_prefix2 = pd.merge(df_a[df_a['match_type'] == 'prefix2'], df_b, left_on='match_key', right_on='Prefix2', how='left') match_prefix3 = pd.merge(df_a[df_a['match_type'] == 'prefix3'], df_b, left_on='match_key', right_on='Prefix3', how='left') match_full = pd.merge(df_a[df_a['match_type'] == 'full'], df_b, left_on='match_key', right_on='FullCode', how='left') final_df = pd.concat([match_prefix2, match_prefix3, match_full]).sort_index()
关键注意点
- 一定要把编码转成字符串类型处理,避免数字补零时丢失前导零(比如数字20转成字符串'20'再补零是'0020',数字类型直接补零会变成2000,完全错误)
- SQL函数可能因数据库不同略有差异,比如PostgreSQL用
LPAD,SQL Server用RIGHT,按需调整即可
内容的提问来源于stack exchange,提问作者user3242036
相关产品推荐
相关产品推荐

