我有两个公司的列表(较长列表中有2k个条目),它们的格式需要统一。我知道这两种格式大约80%的时间都共享存根,因此我正在使用模糊匹配来比较两个列表:
def get_fuzz_score(str1, str2):
from fuzzywuzzy import fuzz
partial_ratio = fuzz.partial_ratio(str1, str2)
return partial_ratio
a = ['Express Scripts', 'Catamaran Corp', 'Banmedica SA (96.7892%)', 'WebMD', 'ODC', 'Caremerge LLC (Stake%)']
b = ['Doctor on Demand', 'Catamaran', 'Express Scripts Holding Corp', 'ODC, Inc.', 'WebMD Health Services', 'Banmedica']
for i in b:
for j in a:
if get_fuzz_score(i, j) > 80:
# process
我很欣赏关于如何优化此任务以提高性能的想法(例如,不必为循环使用2)。
答案 0 :(得分:3)
首先,我将导入from fuzzywuzzy import fuzz
从函数移至文件的开头。
接下来,您似乎想要检查每个元素,因此无论如何都比较all2all,我看不到任何简单的解决方法。
如果数据“不错”,则可以执行一些简单的启发式操作,例如(您发布的示例中的第一个字母-但这取决于数据)。
最诚挚的问候
P.s。如果我的分数足够高,我会发表评论。
答案 1 :(得分:2)
fuzzywuzzy
提供了process.extract*
系列功能来帮助解决此问题,例如:
from fuzzywuzzy import process
a = ['Express Scripts', 'Catamaran Corp', 'Banmedica SA (96.7892%)', 'WebMD', 'ODC', 'Caremerge LLC (Stake%)']
b = ['Doctor on Demand', 'Catamaran', 'Express Scripts Holding Corp', 'ODC, Inc.', 'WebMD Health Services', 'Banmedica']
for name in a:
print(name, process.extract(name, b, limit=3))
将打印出a
中的每个名称以及b
中的前三个匹配项。
这仍然是O(n**2)
,但是由于该库是开放源代码,因此您可以了解extract
的定义方式,也许只需一次preprocessing,而不是每次都希望这样做会加快速度事情很多了
答案 2 :(得分:1)
我假设您同时安装了Fuzzywuzzy和python-Levenshtein。 第二个软件包的安装失败,因此我收到一条消息:
warnings.warn(“使用慢速纯Python SequenceMatcher。安装python-Levenshtein删除此警告”)
您可以使用itertools.product创建笛卡尔乘积:
from itertools import product
from fuzzywuzzy import fuzz
def get_fuzz_score(str1, str2):
partial_ratio = fuzz.partial_ratio(str1, str2)
return partial_ratio
a = ['Express Scripts', 'Catamaran Corp', 'Banmedica SA (96.7892%)', 'WebMD', 'ODC', 'Caremerge LLC (Stake%)']
b = ['Doctor on Demand', 'Catamaran', 'Express Scripts Holding Corp', 'ODC, Inc.', 'WebMD Health Services', 'Banmedica']
for first, second in product(a, b):
if get_fuzz_score(first, second) > 80:
# process
如果您的函数get_fuzz_score没有增长,则可以使其过时:
from itertools import product
from fuzzywuzzy import fuzz #
a = ['Express Scripts', 'Catamaran Corp', 'Banmedica SA (96.7892%)', 'WebMD', 'ODC', 'Caremerge LLC (Stake%)']
b = ['Doctor on Demand', 'Catamaran', 'Express Scripts Holding Corp', 'ODC, Inc.', 'WebMD Health Services', 'Banmedica']
for first, second in product(a, b):
if fuzz.partial_ratio(first, second) > 80:
pass # process