用于模糊字符串比较的好的 Python 模块?

Sov*_*iut 232 python string string-comparison fuzzy-comparison

我正在寻找一个可以进行简单的模糊字符串比较的 Python 模块。具体来说,我想要字符串相似程度的百分比。我知道这可能是主观的,所以我希望找到一个可以进行位置比较以及最长相似字符串匹配等的库。

基本上,我希望找到足够简单的东西来产生单个百分比,同时仍然足够可配置,以便我可以指定要进行的比较类型。

nos*_*klo 249

difflib可以做到。

文档中的示例:

>>> get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'])
['apple', 'ape']
>>> import keyword
>>> get_close_matches('wheel', keyword.kwlist)
['while']
>>> get_close_matches('apple', keyword.kwlist)
[]
>>> get_close_matches('accept', keyword.kwlist)
['except']
Run Code Online (Sandbox Code Playgroud)

一探究竟。它还有其他功能可以帮助您构建自定义内容。

  • @Soviut:例如`difflib.SequenceMatcher(None, 'foo', 'bar').ratio()` 返回一个 0-1 之间的值,可以解释为匹配百分比。对? (33认同)
  • +1 整洁,我不记得以前见过这个 (10认同)
  • +1:很高兴被介绍到我以前没有使用过的模块。 (10认同)
  • 您通过指导我使用 get_close_matches() 为我节省了大量工作 (2认同)

小智 164

Levenshtein Python 扩展和 C 库。

https://github.com/ztane/python-Levenshtein/

Levenshtein Python C 扩展模块包含用于快速计算 - Levenshtein(编辑)距离的函数,以及编辑操作 - 字符串相似度 - 近似中值字符串,以及一般字符串平均 - 字符串序列和集合相似度 它支持普通和 Unicode 字符串。

$ pip install python-levenshtein
...
$ python
>>> import Levenshtein
>>> help(Levenshtein.ratio)
ratio(...)
    Compute similarity of two strings.

    ratio(string1, string2)

    The similarity is a number between 0 and 1, it's usually equal or
    somewhat higher than difflib.SequenceMatcher.ratio(), becuase it's
    based on real minimal edit distance.

    Examples:
    >>> ratio('Hello world!', 'Holly grail!')
    0.58333333333333337
    >>> ratio('Brian', 'Jesus')
    0.0

>>> help(Levenshtein.distance)
distance(...)
    Compute absolute Levenshtein distance of two strings.

    distance(string1, string2)

    Examples (it's hard to spell Levenshtein correctly):
    >>> distance('Levenshtein', 'Lenvinsten')
    4
    >>> distance('Levenshtein', 'Levensthein')
    2
    >>> distance('Levenshtein', 'Levenshten')
    1
    >>> distance('Levenshtein', 'Levenshtein')
    0
Run Code Online (Sandbox Code Playgroud)

  • 只是想注意,对于碰巧在他们的项目中使用 NLTK 的该线程的未来读者,`nltk.metrics.edit_distance('string1', 'string2')` 将计算 `string1` 和 `string2 之间的 Levenshtein 距离`. 因此,如果您像我一样使用 NLTK,除此之外,您可能不需要下载 Levenshtein 库。干杯 (61认同)
  • 现在可以通过 PyPi 获得 (2认同)
  • 虽然 NLTK 有 edit_distance 方法,但它是纯 python 的。如果您大量使用它,python-levenshtein 或 jellyfish 都可以提供巨大的加速...(在我的设置中,我测量了 >10 次) (2认同)

Edi*_*i H 70

正如nosklo所说,使用Python 标准库中的difflib模块。

difflib 模块可以使用SequenceMatcher()对象的ratio()方法返回序列相似性的度量。相似度以 0.0 到 1.0 范围内的浮点数形式返回。

>>> import difflib

>>> difflib.SequenceMatcher(None, 'abcde', 'abcde').ratio()
1.0

>>> difflib.SequenceMatcher(None, 'abcde', 'zbcde').ratio()
0.80000000000000004

>>> difflib.SequenceMatcher(None, 'abcde', 'zyzzy').ratio()
0.0
Run Code Online (Sandbox Code Playgroud)

  • Levenshtein distance 也会遇到同样的问题。如果你不关心这种情况,你应该在比较它们之前对每个参数调用lower()。 (26认同)

小智 39

Jellyfish是一个 Python 模块,它支持许多字符串比较指标,包括语音匹配。与 Jellyfish 的实现相比,Levenstein 编辑距离的纯 Python 实现非常慢。

示例用法:

import jellyfish

>>> jellyfish.levenshtein_distance('jellyfish', 'smellyfish')
2 
>>> jellyfish.jaro_distance('jellyfish', 'smellyfish')
0.89629629629629637
>>> jellyfish.damerau_levenshtein_distance('jellyfish', 'jellyfihs')
1
>>> jellyfish.metaphone('Jellyfish')
'JLFX'
>>> jellyfish.soundex('Jellyfish')
'J412'
>>> jellyfish.nysiis('Jellyfish')
'JALYF'
>>> jellyfish.match_rating_codex('Jellyfish')
'JLLFSH'`
Run Code Online (Sandbox Code Playgroud)

  • 这看起来是一个很棒的库,因为它有_几个_字符串比较算法,而不仅仅是一个:Levenshtein 距离、Damerau-Levenshtein 距离、Jaro 距离、Jaro-Winkler 距离、匹配等级方法比较、Hamming 距离 (6认同)
  • 我很懒,点击链接很难。答案中的例子会很棒。 (2认同)

ber*_*nie 23

我喜欢nosklo 的回答;另一种方法是Damerau-Levenshtein 距离

“在信息论和计算机科学中,Damerau-Levenshtein 距离是两个字符串之间的‘距离’(字符串度量),即有限的符号序列,通过计算将一个字符串转换为另一个字符串所需的最少操作次数给出,其中操作被定义为单个字符的插入、删除或替换,或两个字符的换位。”

来自Wikibooks 的Python 实现:

def lev(a, b):
    if not a: return len(b)
    if not b: return len(a)
    return min(lev(a[1:], b[1:])+(a[0] != b[0]), \
    lev(a[1:], b)+1, lev(a, b[1:])+1)
Run Code Online (Sandbox Code Playgroud)

更多来自 Wikibooks,这为您提供最长公共子串 (LCS)的长度:

def LCSubstr_len(S, T):
    m = len(S); n = len(T)
    L = [[0] * (n+1) for i in xrange(m+1)]
    lcs = 0
    for i in xrange(m):
        for j in xrange(n):
            if S[i] == T[j]:
                L[i+1][j+1] = L[i][j] + 1
                lcs = max(lcs, L[i+1][j+1])
    return lcs
Run Code Online (Sandbox Code Playgroud)


Ste*_*ven 18

还有谷歌自己的google-diff-match-patch(“目前在 Java、JavaScript、C++ 和 Python 中可用”)。

(无法对此发表评论,因为我自己只使用了 python 的 difflib)


shi*_*.ss 8

另一种选择是使用最近发布的软件包FuzzyWuzzy。该包支持的各种功能也在这篇博文中进行了描述。


zen*_*ngr 5

我正在使用像魅力一样的双变音器

一个例子:

>>> dm(u'aubrey')
('APR', '')
>>> dm(u'richard')
('RXRT', 'RKRT')
>>> dm(u'katherine') == dm(u'catherine')
True
Run Code Online (Sandbox Code Playgroud)

更新:水母也有。属于语音编码。