基于多列连接Pandas DataFrame以精准匹配客户与信用卡ID
这种被脏数据坑到没法正常join的情况我太懂了!之前做客户数据整合的时候也碰到过一模一样的问题,直接用pd.join或者merge根本行不通,得先把数据“掰正”再结合模糊匹配来搞,给你分享几个亲测有效的步骤:
脏数据下的DataFrame匹配方案
核心思路是:先标准化清洗每个字段,再通过多字段加权模糊匹配提高准确率,而不是死磕单一的“唯一键”。
1. 先做单字段的标准化清洗
先把每个可能用来匹配的字段统一格式,减少无意义的偏差:
- 姓名字段:
- 统一转成小写:
cust_df['姓名'] = cust_df['姓名'].str.lower() - 去掉空格、特殊符号:
cust_df['姓名'] = cust_df['姓名'].str.replace(r'[^\w\s]', '', regex=True) - 处理常见错别字:可以用
fuzzywuzzy的process.extractOne批量匹配修正,或者自定义一个错别字映射字典(比如把“张三丰”替换成“张三丰”)
- 统一转成小写:
- 出生日期:
- 统一转成日期格式,自动处理不同的字符串写法:
cust_df['出生日期'] = pd.to_datetime(cust_df['出生日期'], errors='coerce').dt.date(errors='coerce'会把无效日期转成NaT,方便后续过滤)
- 统一转成日期格式,自动处理不同的字符串写法:
- 身份证号/手机号:
- 去掉所有非数字字符:
cust_df['身份证号'] = cust_df['身份证号'].str.replace(r'\D', '', regex=True) - 统一长度:比如手机号保留11位,身份证号保留18位,短的可以标记为无效数据,避免干扰匹配
- 去掉所有非数字字符:
2. 多字段加权模糊匹配
清洗完之后,用模糊匹配工具给每个信用卡数据行找最匹配的客户数据行,给不同字段分配不同权重(比如身份证号权重最高,毕竟重复概率极低)。这里推荐用rapidfuzz,比老牌的fuzzywuzzy快很多。
示例代码:
from rapidfuzz import fuzz import pandas as pd # 定义匹配函数:给cc_df的每一行找最优匹配的cust_df行 def find_best_match(cc_row): # 给各字段设置权重,优先级:身份证>手机号>出生日期>姓名 weight_map = {'身份证号':0.4, '手机号':0.3, '出生日期':0.2, '姓名':0.1} # 计算每个客户行的综合匹配得分 def get_total_score(cust_row): total = 0 # 身份证/手机号/出生日期:完全匹配直接拿满分 if str(cc_row['身份证号']) == str(cust_row['身份证号']): total += weight_map['身份证号'] * 100 if str(cc_row['手机号']) == str(cust_row['手机号']): total += weight_map['手机号'] * 100 if cc_row['出生日期'] == cust_row['出生日期']: total += weight_map['出生日期'] * 100 # 姓名:用模糊匹配得分 name_score = fuzz.ratio(str(cc_row['姓名']).lower(), str(cust_row['姓名']).lower()) total += weight_map['姓名'] * name_score return total # 给cust_df临时加得分列,找到最高分的行 cust_df['匹配得分'] = cust_df.apply(get_total_score, axis=1) best_match = cust_df.loc[cust_df['匹配得分'].idxmax()] return pd.Series([best_match['CUST_ID'], best_match['匹配得分']]) # 给cc_df添加匹配结果 cc_df[['匹配的CUST_ID', '匹配得分']] = cc_df.apply(find_best_match, axis=1) # 设置阈值过滤低质量匹配,比如只保留得分>80的结果 cc_df = cc_df[cc_df['匹配得分'] > 80]
3. 手动校验补漏
机器匹配不可能100%准确,尤其是得分在60-80之间的模糊匹配结果,一定要人工校验修正。你可以把校验后的正确匹配做成一个映射字典,下次匹配直接复用,能省不少事。
如果你的数据量特别大(百万级以上),逐行apply会很慢,推荐用recordlinkage库,它专门针对大规模数据的模糊匹配做了优化,效率会高很多。
内容的提问来源于stack exchange,提问作者Agung Sriwongo
相关产品推荐
相关产品推荐

