Pandas在同一列中用模糊匹配替换字符串

2024-06-28 21:00:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我在数据帧中有一列是这样的:

 OWNER
 --------------
 OTTO J MAYER
 OTTO MAYER 
 DANIEL J ROSEN
 DANIEL ROSSY
 LISA CULLI
 LISA CULLY 
 LISA CULLY
 CITY OF BELMONT
 CITY OF BELMONT CITY

我的数据框中的一些名称拼写错误或有多余/缺少的字符。我需要一个列,其中的名称被替换为任何密切匹配在同一列。但是,所有相似的名称都需要在同一个名称下进行分组

例如,这就是我对上面数据框的期望:

 NAME
 --------------
 OTTO J MAYER
 OTTO J MAYER 
 DANIEL J ROSEN
 DANIEL ROSSY
 LISA CULLY
 LISA CULLY 
 LISA CULLY
 CITY OF BELMONT
 CITY OF BELMONT

奥托梅耶尔被奥托梅耶尔取代,因为他们都非常相似。但以理一家还是老样子,因为不太相配。LISA CULL都有相同的值等等

我有一些代码是从另一篇关于堆栈溢出的文章中得到的,这篇文章试图解决一些类似的问题,但是它们使用了一个名称字典。但是,我很难重新编写他们的代码来产生我需要的输出

以下是我目前的情况:

d = pd.DataFrame({'OWNER' : pd.Series(['OTTO J MAYER', 'OTTO MAYER','DANIEL J ROSEN','DANIEL ROSSY',
                                      'LISA CULLI', 'LISA CULLY'])})
names = d['OWNER']
names = names.values
names

import difflib 


def best_match(tokens, names):
    for i,t in enumerate(tokens):
        closest = difflib.get_close_matches(t, names, n=1)
        if len(closest) > 0:
            return i, closest[0]
    return None

def fuzzy_replace(x, y):

    names = y # just a simple replacement list
    tokens = x.split()
    res = best_match(tokens, y)
    if res is not None:
        pos, replacement = res
        return u" ".join(tokens)
    return x

d["OWNER"].apply(lambda x: fuzzy_replace(x, names))


Tags: of数据名称cityreturnnamesownerdaniel
1条回答
网友
1楼 · 发布于 2024-06-28 21:00:55

实际上^{}适合于该任务,但是将名称拆分为标记没有好处。为了区分指定的名称,我们必须将截止值分数提高到0.8左右,并确保返回所有可能的名称,将最大值提高到len(names)。然后我们有两个案例来决定选择哪个名称:

  • 如果一个名字比其他名字出现的次数多,选择那个名字
  • 否则,选择首先出现的一个
def fuzzy_replace(x, names):
    aliases = difflib.get_close_matches(x, names, len(names), .8)
    closest = pd.Series(aliases).mode()
    closest = aliases[0] if closest.empty else closest[0]
    d['OWNER'].replace(aliases, closest, True)

for x in d["OWNER"]: fuzzy_replace(x, d['OWNER'])

相关问题 更多 >