Levenshtein module implements the well-known Levenshtein fuzzy matching algorithm along with other related algorithms (e.g. Jaro, Jaro-Winkler, etc).
Levenshtein.jaro_winkler() is a string similarity metric that gives more weight to a common prefix, as spelling mistakes are more likely to occur near ends of words. It returns a numeric value from 0.0 to 1.0 where 1.0 is the most similar.
Levenshtein.distance() calculates the minimum number of insertions, deletions, and substitutions required to change one sequence into the other.
import pandas as pd
import Levenshtein
data = [[1, 'LemonFarms', 'Lemon Farms Inc'],
[2, 'Peachtree', 'PeachTree Farms'],
[3, 'Tomato Grove', 'Orange Cheetah Far']
]
df = pd.DataFrame(data, columns=['Match ID', 'Name Left', 'Name Right'])
df['score'] = df[['Name Left', 'Name Right']].apply(lambda x: Levenshtein.jaro_winkler(*x), axis=1)
df['distance'] = df[['Name Left', 'Name Right']].apply(lambda x: Levenshtein.distance(*x), axis=1)
print(df)
Output:
Match ID Name Left Name Right score distance
0 1 LemonFarms Lemon Farms Inc 0.933333 5
1 2 Peachtree PeachTree Farms 0.884444 7
2 3 Tomato Grove Orange Cheetah Far 0.431481 17
To improve the score, you can convert the values to lower case characters before calculating the similarity score so the score is case insensitive.
df['score'] = df[['Name Left', 'Name Right']].apply(
lambda x: Levenshtein.jaro_winkler(x[0].lower(), x[1].lower()), axis=1)
This changes the score of Peachtree vs PeachTree Farms from 0.884444 to 0.920000. You can use a cut-off threshold; e.g. score >= 0.9 to indicate that strings are well matched and < 0.9 that they are badly matched.