【问题标题】:Pandas replace strings with fuzzy match in the same columnPandas 在同一列中用模糊匹配替换字符串
【发布时间】:2020-03-13 05:51:44
【问题描述】:

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

 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

OTTO MAYER 被 OTTO J MAYER 取代,因为它们非常相似。 DANIEL 保持不变,因为它们不匹配。 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))

【问题讨论】:

    标签: python regex pandas fuzzy-comparison difflib


    【解决方案1】:

    确实difflib.get_close_matches 适合这项任务,但将名称拆分为标记并不好。为了区分指定的名称,我们必须将 cutoff 分数提高到大约 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'])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-14
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      相关资源
      最近更新 更多