Python字符串模糊匹配
四种模糊匹配方法
1、ratio()——使用纯Levenshtein Distance进行匹配。
2、partial_ratio()——基于最佳的子串(substrings)进行匹配
3、token_sort_ratio——对字符串进行标记(tokenizes)并在匹配之前按字母顺序对它们进行排序
4、token_set_ratio——对字符串进行标记(tokenizes)并比较交集和余数
下面的代码片段突出显示了这四种算法与一些通用用例之间的区别:
1、当比较字符串因标点符号而不同的情况:
fuzz.ratio("test is fuzzywuzzy","test is fuzzywuzzy") #抽取匹配
fuzz.ratio("test is fuzzywuzzy","test is fuzzywuzzy..") #有标点
不一致的子串是我们常见的问题。为了解决它,当两个字符串具有明显不同的长度时(例如下面的情况),我们使用称为“best partial”的启发式算法。如果较短的字符串是长度m,而较长的字符串是长度n,我们基本上对最佳匹配长度为m的子字符串的得分感兴趣可以采用下面的辅助算法,fuzzywuzzy封装了partial_ratio函数。
fuzz.partial_ratio("test is fuzzywuzzy","test is fuzzywuzzy..") #有标点
token_sort_ratio方法涉及对有问题的字符串进行标记,按字母顺序对标记进行排序,然后将它们连接回字符串。例如:
"new york mets vs atlanta braves" →→ "atlanta braves mets new vs york"
fuzz.token_sort_ratio("test is fuzzywuzzy","test is fuzzywuzzy!!") #标点
token_set_ratio方法类似,但更灵活一点。在这里,我们对两个字符串进行标记,但不是立即进行排序和比较,而是将标记分为两组:交集和余数。我们使用这些集合来构建比较字符串。
s1 = "mariners vs angels" s2 = "los angeles angels of anaheim at seattle mariners" #使用token_sort_ratio方法没有用,因为第二个(更长)字符串有太多的额外token与排序交错。我们最终会比较: t1 = "angels mariners vs" t2 = "anaheim angeles angels los mariners of seattle vs" #不是很有用。相反,set方法允许我们检测“angels”和“mariners ”对两个字符串都是通用的,并将它们分开#(设置交集)。现在我们构造并比较以下形式的字符串: t0 = [SORTED_INTERSECTION] t1 = [SORTED_INTERSECTION] + [SORTED_REST_OF_STRING1] t2 = [SORTED_INTERSECTION] + [SORTED_REST_OF_STRING2] # 然后比较每一对。 ''' 这里的直觉是,因为SORTED_INTERSECTION组件总是完全相同, 所以当(a)构成完整字符串的较大百分比时,分数增加,并且(b)字符串余数更相似。在我们的例子中 ''' t0 = "angels mariners" t1 = "angels mariners vs" t2 = "angels mariners anaheim angeles at los of seattle" fuzz.ratio(t0, t1) ⇒ 90 fuzz.ratio(t0, t2) ⇒ 46 fuzz.ratio(t1, t2) ⇒ 50 fuzz.token_set_ratio("mariners vs angels", "los angeles angels of anaheim at seattle mariners") ⇒ 90 ''' 还有其他方法可以组合这些值。例如,我们可以采用平均值或最小值。但根据我们的经验,“尽可能最佳匹配”的方法似乎可以提供最佳的现实生活结果。当然,使用集合意味着重复的令牌会在转换中丢失。 ''' fuzz.token_set_ratio("Sirhan, Sirhan", "Sirhan") ⇒ 100
fuzz.token_set_ratio("test is fuzzywuzzy","test is fuzzywuzzy!!")
2、比较字符串有不同的情况:
fuzz.ratio("Test is Fuzzywuzzy","test is fuzzywuzzy") #ratio - 大小写
fuzz.partial_ratio("Test is Fuzzywuzzy","test is fuzzywuzzy")#patial_ratio - 大小写
-
fuzz.token_sort_ratio("Test is Fuzzywuzzy","test is fuzzywuzzy") #token_sort_ratio -大小写
-
fuzz.token_set_ratio("Test is Fuzzywuzzy","test is fuzzywuzzy") #token_set_ratio-大小写
3、比较字符串顺序不同的情况:
fuzz.ratio("Test is Fuzzywuzzy","fuzzywuzzy is test ")
fuzz.partial_ratio("Test is Fuzzywuzzy","fuzzywuzzy is test ")
fuzz.token_set_ratio("Test is Fuzzywuzzy","fuzzywuzzy is test ")
fuzz.token_sort_ratio("Test is Fuzzywuzzy","fuzzywuzzy is test ")
4、比较字符串是子集
fuzz.ratio("Test is Fuzzywuzzy","fuzzywuzzy ")
fuzz.partial_ratio("Test is Fuzzywuzzy","fuzzywuzzy ")
fuzz.token_sort_ratio("Test is Fuzzywuzzy","fuzzywuzzy ")
fuzz.token_set_ratio("Test is Fuzzywuzzy","fuzzywuzzy ")
与选择列表进行比较
下面的代码片段演示了如何使用四个scorers(ratio, partial_ratio, token_sort_ratio, token_set_ratio)中一个,对一个字符串的列表来获得分数。scorer的选择取决于数据的性质和所需结果的性质。
我们还可以使用"socer_cutoff"参数来设置最佳匹配分数的阈值。如果最佳匹配分数低于阈值,则会返回None,如下面的代码片段所示:
将FuzzyMatch应用于整个数据集
下面的代码片段淹死了如何将模糊屁哦EI应用与整个dataset_1列中,以针对dataset_2的列返回最佳分数,其中计分器为"token_set_ratio",score_cutoff为90