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

使用difflib匹配DataFrame中CallType列未获预期结果的问题

呼叫类型映射问题及解决方案

问题描述

原始DataFrame数据:

CallType
0         IN
1        OUT
2       a_in
3       asms
4   INCOMING
5   OUTGOING
6  A2P_SMSIN
7        ain
8       aout

期望映射结果:

CallType
0       IN
1       OUT
2       IN
3       SMS
4       IN
5       OUT
6       SMS
7       IN
8       OUT

尝试使用difflib.get_close_matches实现,但仅匹配到IN和OUT,其余结果为空列表:

import pandas as pd
import difflib

CALL_TYPE=['IN','OUT','SMS','VOICE','SMT']

def test1():
    final_file_data = pd.DataFrame({
        'CallType': ['IN', 'OUT', 'a_in',
                         'asms', 'INCOMING', 'OUTGOING','A2P_SMSIN',
                         'ain', 'aout']})

    print(final_file_data)
    final_file_data['CallType'] = final_file_data['CallType'].apply(lambda x: difflib.get_close_matches(x, CALL_TYPE, n=1))

实际输出:

CallType
0     [IN]
1    [OUT]
2       []
3       []
4       []
5       []
6       []
7       []
8       []

问题原因

difflib.get_close_matches默认使用字符串整体相似度(基于编辑距离的ratio值),阈值为0.6。而你的数据中,a_in、INCOMING这类字符串和目标关键词(如IN)的整体相似度远低于0.6,因此无法匹配。例如INCOMING和IN的相似度仅约0.33,达不到阈值要求。

解决方案

方法一:基于关键词包含的自定义映射

通过判断目标关键词是否存在于原字符串中(忽略大小写),实现精准映射:

import pandas as pd

CALL_TYPE = ['IN', 'OUT', 'SMS', 'VOICE', 'SMT']

def map_call_type(x):
    x_lower = x.lower()
    for typ in CALL_TYPE:
        if typ.lower() in x_lower:
            return typ
    return x  # 无匹配时返回原值

def test1():
    final_file_data = pd.DataFrame({
        'CallType': ['IN', 'OUT', 'a_in', 'asms', 'INCOMING', 'OUTGOING','A2P_SMSIN', 'ain', 'aout']
    })
    print("原始数据:")
    print(final_file_data)
    final_file_data['CallType'] = final_file_data['CallType'].apply(map_call_type)
    print("\n映射后结果:")
    print(final_file_data)

test1()

方法二:正则表达式匹配

构建正则模式,优先匹配长关键词(避免短关键词误匹配),实现映射:

import pandas as pd
import re

CALL_TYPE = ['IN', 'OUT', 'SMS', 'VOICE', 'SMT']
# 按关键词长度从长到短排序,避免短关键词优先匹配
pattern = re.compile('|'.join(sorted(CALL_TYPE, key=len, reverse=True)), flags=re.IGNORECASE)

def map_call_type(x):
    match = pattern.search(x)
    return match.group().upper() if match else x

def test1():
    final_file_data = pd.DataFrame({
        'CallType': ['IN', 'OUT', 'a_in', 'asms', 'INCOMING', 'OUTGOING','A2P_SMSIN', 'ain', 'aout']
    })
    print("原始数据:")
    print(final_file_data)
    final_file_data['CallType'] = final_file_data['CallType'].apply(map_call_type)
    print("\n映射后结果:")
    print(final_file_data)

(不推荐)调低difflib阈值

如果一定要使用difflib,可以调低匹配阈值,但可能出现错误匹配:

final_file_data['CallType'] = final_file_data['CallType'].apply(
    lambda x: difflib.get_close_matches(x, CALL_TYPE, n=1, cutoff=0.3)[0] if difflib.get_close_matches(x, CALL_TYPE, n=1, cutoff=0.3) else x
)

该方法可能导致asms匹配到SMT而非SMS,因此不建议使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:53:12