如何在python中使用Fuzzywuzzy获得最大匹配字符串

时间:2018-12-28 10:08:14

标签: python python-3.x

我正在尝试通过使用python中的Fuzzywuzzy库来匹配字符串,以获取字符串中的最大可能性匹配项。

import pandas as pd
import re
from fuzzywuzzy import fuzz
from fuzzywuzzy import process

input_row = ['HINDUSTAN-CONSTRUCTION-COMPANY-LIMITED', 'HINDUSTAN-HOUSING-COMPANY-LIMITED']

matches = ['Akruti Group', 'Alps Entreprises', 'Amur real Estate Pvt Ltd.','Ansal Housing & Construction Ltd.','Vikas Construction','Jalaram Jagruti Developers Pvt. Ltd.', 'Hindustan Ltd']

data = []

for i in range(len(input_row)):

    data.append((fuzz.ratio(input_row[i], matches), input_row))

    print (max(fuzz.ratio(input_row[i], matches)))

获取错误:

TypeError: 'int' object is not iterable

预期输出:

    String                                 best_matches, Percentage
'HINDUSTAN-CONSTRUCTION-COMPANY-LIMITED', 'Hindustan Ltd', 50
'HINDUSTAN-HOUSING-COMPANY-LIMITED', 'Hindustan Ltd', 65

2 个答案:

答案 0 :(得分:0)

您的循环不正确。 fuzz.ratio使用两个字符串并返回一个int,您可以提供一个matches它是一个字符串列表。

另外,由于您的匹配项是子字符串,因此您可能希望使用partial_ratio而不是ratio来获得所需的结果。

应该起作用的示例:

for item in input_row:
    data = []
    for match in matches:
        data.append((item, match, fuzz.partial_ratio(match, item)))
    print (max(data, key=lambda x: x[2]))

改善结果

案例

在您提供的示例中,'Hindustan Ltd'的匹配结果不好。您可能想通过在两个字符串上使用lower进行不区分大小写的比较

名词

"Construction"等某些名词在您的数据集中很长且很常见,例如,'Vikas Construction'的得分要比'Hindustan Ltd'高。如果名词数量很少,减少这种情况的一个好方法是使用词典来减少相似度:

'Hindustan Construction' 然后将其替换为两个字符串

shorthands = {'construction':'ctt', 'limited': 'ltd', 'housing': 'hsg'}

答案 1 :(得分:0)

ratio函数返回一个整数,并且max期望一个可迭代的(以计算最大迭代次数),使用max调用以更改列表理解的行来打印该行:< / p>

print(max(fuzz.ratio(input_row[i], j) for j in matches))

尽管要打印预期的输出,更适合使用extractOne模块中的process模块,该模块提取最相似的字符串:

for word in input_row:    
    print(word+', ', ', '.join(map(str,process.extractOne(word, matches))))

作为旁注,我还更改了for循环,因为不需要迭代索引,可以直接通过单词

进行迭代。