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

如何基于子串条件高效实现两个手机号DataFrames的左连接合并

基于子串后缀匹配的DataFrame高效左连接实现

需求描述

处理手机号相关的两个DataFrames,需要基于子串匹配条件进行左连接,要求保留所有匹配组合(即一条主表数据对应多条子表匹配项时,需列出全部组合)。原方案通过生成笛卡尔积后过滤子串,数据量大时性能极差,需高效实现方式。

示例数据

PHONES(主表)

idphone
1+12399998888
2+12377776666
3+1233399998888

PHONES_NO_EXT(匹配表)

idphone
199998888
299998888
377776666

期望结果RESULT_NEEDED

idphonephone_no_ext
1+1239999888899998888
1+1239999888899998888
2+1237777666677776666
3+123339999888899998888
3+123339999888899998888

注:主表每条数据在匹配表中至少存在一个匹配项,匹配规则为匹配表的phone是主表phone的后缀子串。

高效实现方案

核心思路

将子串匹配转化为等值匹配:由于匹配表的phone是主表phone的后缀,先提取主表phone的对应长度后缀,再通过该后缀列与匹配表的phone列做左连接,直接得到所有匹配组合,完全避免笛卡尔积的生成。

代码实现

import pandas as pd

# 1. 构造示例数据(替换为你的实际DataFrame)
phones = pd.DataFrame({
    'id': [1, 2, 3],
    'phone': ['+12399998888', '+12377776666', '+1233399998888']
})

phones_no_ext = pd.DataFrame({
    'id': [1, 2, 3],
    'phone': ['99998888', '99998888', '77776666']
})

# 2. 提取主表手机号的匹配后缀(长度与匹配表手机号一致)
# 若匹配表手机号长度不统一,可取最大长度:ext_length = phones_no_ext['phone'].str.len().max()
ext_length = len(phones_no_ext['phone'].iloc[0])
phones['phone_suffix'] = phones['phone'].str[-ext_length:]

# 3. 基于后缀列做左连接,保留所有匹配组合
merged_result = phones.merge(
    phones_no_ext,
    left_on='phone_suffix',
    right_on='phone',
    how='left'
)

# 4. 整理结果列名与结构
final_result = merged_result.rename(
    columns={'phone_x': 'phone', 'phone_y': 'phone_no_ext'}
)[['id_x', 'phone', 'phone_no_ext']].rename(columns={'id_x': 'id'})

print(final_result)

方案优势

  • 性能高效:避免了O(n*m)复杂度的笛卡尔积,转为O(n+m)的等值匹配,pandas内部对该操作有高度优化,数据量越大性能提升越明显。
  • 扩展性强:无需修改核心逻辑即可适配更大规模的数据集,若匹配表手机号长度不固定,只需调整后缀长度的计算方式即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:43:14