我正在尝试通过使用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
答案 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循环,因为不需要迭代索引,可以直接通过单词
进行迭代。