Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫在同一列中用模糊匹配替换字符串_Python_Regex_Pandas_Fuzzy Comparison_Difflib - Fatal编程技术网

Python 熊猫在同一列中用模糊匹配替换字符串

Python 熊猫在同一列中用模糊匹配替换字符串,python,regex,pandas,fuzzy-comparison,difflib,Python,Regex,Pandas,Fuzzy Comparison,Difflib,我在数据帧中有一列,如下所示: OWNER -------------- OTTO J MAYER OTTO MAYER DANIEL J ROSEN DANIEL ROSSY LISA CULLI LISA CULLY LISA CULLY CITY OF BELMONT CITY OF BELMONT CITY 我的数据框中的一些名称拼写错误,或者有多余/缺少的字符。我需要一个列,其中的名称替换为同一列中的任何密切匹配项。但是,所有相似的名称都需要在同一个名称下分

我在数据帧中有一列,如下所示:

 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取代,因为两者非常相似。但以理一家还是老样子,因为他们不太般配。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))

的确,它适合于此任务,但将名称拆分为标记并没有什么好处。为了区分指定的名称,我们必须将截止分数提高到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'])