[英]how to efficiently compare two dictionaries of lists of strings using difflib?
我有两个大型列表字典。 列表的所有元素都是字符串。 我想将所有内容与所有内容进行比较并计算它们各自的相似性 - 但我使用的天真的方式显然非常缓慢并且根本无法扩展:
import numpy as np
import difflib
first_dict = {"first1" : ["aa", "bb","cc", "dd"], "first2" : ["ff", "gg"]}
second_dict = {"second1" : ["cc", "dd", "jj", "aa", "bb"], "second2" : ["ff", "gg"], "second3" : ["hh", "ii"]}
mat = np.empty((len(second_dict), len(first_dict)))
for i, second in enumerate(second_dict.keys()):
for j, first in enumerate(first_dict.keys()):
sm = difflib.SequenceMatcher(None, sorted(first_dict[first]), sorted(second_dict[second]))
mat[i, j] = sm.ratio()
print(mat)
有没有一种聪明的方法可以加快速度?
您的代码似乎合法。 我做了一些小调整,每个循环可以减少几微秒:
sorted
的调用,因为difflib
可以计算与quick_ratio
的顺序无关的比较(在此处查看文档以了解ratio
、 quick_ratio
和real_quick_ratio
之间的差异)。enumerate
不需要通过i
和j
访问mat
。first_dict[index]
和second_dict[index]
对列表的访问def naive_ratio_comparison(first_dict, second_dict):
mat = []
for second in second_dict.values():
for first in first_dict.values():
sm = difflib.SequenceMatcher(None, first, second)
mat.append(sm.quick_ratio())
result = np.resize(mat, (len(second_dict), len(first_dict)))
return result
如果一个 dict 有M
条目,另一个有N
,那么您将不得不进行M*N
.ratio()
调用。 没有办法解决这个问题,而且代价高昂。
但是,您可以轻松地安排只进行M+N
排序而不是(如图所示) M*N
排序。
对于计算.ratio()
,最有价值的提示在文档中:
SequenceMatcher
计算并缓存有关第二个序列的详细信息,因此如果要将一个序列与多个序列进行比较,请使用set_seq2()
设置常用序列一次,然后重复调用set_seq1()
,对其他每个序列执行一次。
把所有这些放在一起:
firsts = list(map(sorted, first_dict.values())) # sort these only once
sm = difflib.SequenceMatcher(None)
for i, second in enumerate(second_dict.values()):
sm.set_seq2(sorted(second))
for j, first in enumerate(firsts):
sm.set_seq1(first)
mat[i, j] = sm.ratio()
这应该会产生完全相同的结果。 为了尽量减少昂贵的.set_seq2()
调用的数量,当然,最好将较短的 dict 称为“second_dict”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.