繁体   English   中英

将名称列表与数据质量差的列匹配(Python)

[英]Matching a list of names to a column with bad data quality (Python)

我有一个包含5列的表格,其中之一是数据质量糟糕的名称列表。 我设法在R中尽可能地清理了它,但它仍然看起来像这样(格式化为便于阅读的代码):

Neville Longbottomx
Severus Snape Slyth
Granger, Hermioone
Miss Lovegoo
Nott: Theodore
Mr Potter Gryffindor
Malfoy, Draco
Bulstrode, Millicent
McGonagall, Minerv
Seamus Finnigan Mister
Miss Abbott, Hannah
Ernie Macmillan M
Dumbledore, Albus
Parkinson, Pans" Slyth

现在,我还有另一个名称如下的列表:

Lovegood, Luna
Longbottom, Neville
Macmillan, Ernie
Nott, Theodore
Parkinson, Pansy

我想在第一个列表的第二个列表中找到名称。 我在此查找了不同的文章并尝试了此方法,因为ngrams似乎是一种明智的选择,但我首先遇到此错误:

def ngrams(string, n=3):
    string = re.sub(r'[,-./]|\sBD',r'', string)
    ngrams = zip(*[string[i:] for i in range(n)])
    return [''.join(ngram) for ngram in ngrams]


company_names = names['NAMECOLUMN']
vectorizer = TfidfVectorizer(min_df=1, analyzer=ngrams)
tf_idf_matrix = vectorizer.fit_transform(company_names)

Traceback (most recent call last):

  File "<ipython-input-4-687c2896bcf2>", line 17, in <module>
    tf_idf_matrix = vectorizer.fit_transform(company_names)

  File "C:\Program Files\Anaconda3\lib\site-packages\sklearn\feature_extraction\text.py", line 1305, in fit_transform
    X = super(TfidfVectorizer, self).fit_transform(raw_documents)

  File "C:\Program Files\Anaconda3\lib\site-packages\sklearn\feature_extraction\text.py", line 817, in fit_transform
    self.fixed_vocabulary_)

  File "C:\Program Files\Anaconda3\lib\site-packages\sklearn\feature_extraction\text.py", line 752, in _count_vocab
    for feature in analyze(doc):

  File "<ipython-input-4-687c2896bcf2>", line 10, in ngrams
    string = re.sub(r'[,-./]|\sBD',r'', string)

  File "C:\Program Files\Anaconda3\lib\re.py", line 182, in sub
    return _compile(pattern, flags).sub(repl, string, count)

TypeError: expected string or bytes-like object

并尝试作为字符串后:

ValueError: empty vocabulary; perhaps the documents only contain stop words

我什至不确定我是否会朝着正确的方向前进,但这是我所能找到的最佳链接,它与我需要做的事情相对应,而且我不确定我需要做的更好。 我不是Python的完全菜鸟,这无济于事:(因此,我希望您对我有所耐心。

las,我将非常感谢您提供有关如何解决上述问题和/或代码的建议。

提前非常感谢!

编辑:完全忘记提及理想的解决方案将匹配并从我的丑陋表中获取完整行,因为我需要存储在其他列中的名称信息。

我建议看一下fuzzywuzzy软件包来进行这种匹配。 为了满足您的需求,我认为过滤fuzz.token_sort_ratiofuzz.token_set_ratio分数大于某个阈值(例如75%)的名称就足够了

>>> from fuzzywuzzy import fuzz
>>> from itertools import takewhile
>>> 
>>> lstA = ['Neville Longbottomx', 'Severus Snape Slyth', 'Granger, Hermioone', 'Miss Lovegoo', 'Nott: Theodore', 'Mr Potter Gryffindor', 'Malfoy, Draco', 'Bulstrode, Millicent', 'McGonagall, Minerv', 'Seamus Finnigan Mister', 'Miss Abbott, Hannah', 'Ernie Macmillan M', 'Dumbledore, Albus', 'Parkinson, Pans" Slyth']
>>> lstB = ['Lovegood, Luna', 'Longbottom, Neville', 'Macmillan, Ernie', 'Nott, Theodore', 'Parkinson, Pansy']
>>> 
>>> dict((name,next(takewhile(lambda n: fuzz.token_sort_ratio(n, name)>75, lstA), '')) for name in lstB)
{'Lovegood, Luna': '', 'Longbottom, Neville': 'Neville Longbottomx', 'Macmillan, Ernie': '', 'Nott, Theodore': '', 'Parkinson, Pansy': ''}

您可以使用模糊匹配算法:)

from fuzzywuzzy import fuzz

a = ['Neville Longbottomx','Severus Snape Slyth','Granger, Hermioone','Miss Lovegoo',
    'Nott: Theodore','Mr Potter Gryffindor','Malfoy, Draco','Bulstrode, Millicent',
    'McGonagall, Minerv','Seamus Finnigan Mister','Miss Abbott, Hannah','Ernie Macmillan M',
    'Dumbledore, Albus','Parkinson, Pans" Slyth']

b = ['Lovegood, Luna','Longbottom, Neville','Macmillan, Ernie','Nott, Theodore','Parkinson, Pansy']
get_match_a = []
for name1 in b:
    for name2 in a:
        if fuzz.partial_ratio(name2,name1)>50: # Tune this to fit your need
            get_match_a.append(name2)
            #print(name1,':',name2,'||',fuzz.partial_ratio(name2,name1))
            #uncomment above to see the matching

正如您在下面看到的,它运行良好。 我希望这将引导您到您想去的地方:) 在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM