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

pandas中键列拼写不一致时合并两个dataframe的问题咨询

问题原因分析与修复方案

1. 第一个报错 TypeError: expected string or bytes-like object 原因与修复

原因

虽然你确认FULL_NAME是object类型,但pandas的object列允许混合存储多种类型,只要列里存在NaN、None等空值,或者个别值是数字/布尔等非字符串类型,传入fuzzywuzzy的匹配函数时就会触发类型错误。

修复前置步骤:统一预处理姓名列

先对两个表的姓名列做标准化处理,同时解决你提到的多余空格、前缀问题,也避免类型错误:

import pandas as pd
import re
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
import difflib

def clean_name(name):
    # 先处理空值,转成空字符串
    if pd.isna(name):
        return ""
    # 强制转成字符串类型
    name = str(name)
    # 去掉所有多余空格(前后空格、中间连续多空格)
    name = re.sub(r'\s+', ' ', name.strip())
    # 去掉Mr. Ms. Mrs. Dr. 这类前缀,可根据自身场景补充更多前缀规则
    name = re.sub(r'^(Mr\.|Ms\.|Mrs\.|Dr\.|Prof\.)\s', '', name, flags=re.IGNORECASE)
    return name

# 对两个表的姓名列做清洗
df1['clean_name'] = df1['FULL_NAME'].apply(clean_name)
df2['clean_name'] = df2['FULL_NAME'].apply(clean_name)

# 过滤掉清洗后是空字符串的无效行,避免无效匹配
df1_valid = df1[df1['clean_name'] != ''].copy()
df2_valid = df2[df2['clean_name'] != ''].copy()

2. 第二个报错 IndexError: list index out of range 原因与修复

原因

difflib.get_close_matches 如果没有找到符合相似度阈值的匹配项,会返回空列表,直接取[0]就会触发索引越界错误;同理fuzzywuzzy的process.extractOne如果找不到匹配会返回None,直接取[0]也会报错。

修复匹配逻辑

匹配时先判断是否有返回结果,没有的话填占位值(比如无匹配),避免报错:

模糊匹配代码(fuzzywuzzy版本,对姓名缺字、顺序颠倒场景适配更好)

def get_best_match(name, candidate_list, threshold=80):
    # threshold为匹配相似度阈值,范围0-100,分数越高匹配越严格,可根据效果调整
    match_res = process.extractOne(name, candidate_list, scorer=fuzz.token_sort_ratio)
    if match_res and match_res[1] >= threshold:
        return match_res[0]
    else:
        return "无匹配"

# 执行匹配
df1_valid['best_match_clean'] = df1_valid['clean_name'].apply(
    lambda x: get_best_match(x, df2_valid['clean_name'].tolist())
)

# 将匹配到的清洗后姓名关联回df2的原始信息,完成合并
merged_df = df1_valid.merge(
    df2_valid,
    left_on='best_match_clean',
    right_on='clean_name',
    how='left',
    suffixes=('_df1', '_df2')
)

模糊匹配代码(difflib版本)

def get_close_match(name, candidate_list, cutoff=0.6):
    # cutoff为相似度阈值,范围0-1,越高匹配越严格,可根据效果调整
    matches = difflib.get_close_matches(name, candidate_list, n=1, cutoff=cutoff)
    return matches[0] if matches else "无匹配"

df1_valid['best_match_clean'] = df1_valid['clean_name'].apply(
    lambda x: get_close_match(x, df2_valid['clean_name'].tolist())
)

# 合并逻辑和上述fuzzywuzzy版本一致
merged_df = df1_valid.merge(
    df2_valid,
    left_on='best_match_clean',
    right_on='clean_name',
    how='left',
    suffixes=('_df1', '_df2')
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 14:15:00