seatgeek / fuzzywuzzy

Fuzzy String Matching in Python
http://chairnerd.seatgeek.com/fuzzywuzzy-fuzzy-string-matching-in-python/
GNU General Public License v2.0
9.2k stars 878 forks source link

String fuzzy-matching From R to Python #317

Open Magic-fan opened 3 years ago

Magic-fan commented 3 years ago

I am trying to use string fuzzy-matching with both R and Python. I am actually using two packages:

When I try amatch("PARI", c("HELLO", "WORLD"), maxDist = 2) on R, I get NA as a result, which is intuitive. But when I try the same thing with Python : process.extract("PARI", ["HELLO", "WORLD"], limit = 2), I get [('world', 22), ('HELLO', 0)]

How could I get the same result as in R ?

Thanks in advance

maxbachmann commented 3 years ago

There are a couple of important differences between the two packages: 1) In FuzzyWuzzy limit specifies how many elements you want extract to return. extract does not provide an argument to specify a maxDist. For this purpose you would have to use the extractBests with the score_cutoff argument.

2) Stringdist appears to use an edit distance, while FuzzyWuzzy only provides normalized string metrics (0-100). So you would have to use e.g. score_cutoff=90. You can specify the string metric using the scorer argument. 3) FuzzWuzzy preprocesses strings by default in the extract function (lowercase + replaces non alphanumeric characters). You can disable this using processor=None

As an alternative you could use RapidFuzz which allows the usage of edit distances and a score_cutoff parameter in the extract function:

>>> from rapidfuzz import process, string_metric
>>> process.extract("PARI", ["HELLO", "WORLD"], processor=None, scorer=string_metric.levenshtein, score_cutoff=2)
[]
>>> process.extract("HELL", ["HELLO", "WORLD"], processor=None, scorer=string_metric.levenshtein, score_cutoff=2)
[('HELLO', 1, 0)]