Сопоставление данных в python (нечеткое, Левенштейн?) - PullRequest
0 голосов
/ 25 мая 2020

Я хотел бы сделать что-то вроде нечеткого v-поиска в Excel, но в python. У меня есть список из ~ 10 000 конкатенированных строк, например:

JohnSmith5159LosAngeles
JaneDo7729NewYork
etc

, которые я хотел бы найти похожие строки среди списка, отформатированного таким же образом (и я хотел бы указать% совпадения), и поставить совпадение в соседнем столбце. Что, надеюсь, вернет что-то вроде:

JohnSmith5159LosAngeles |  JohnDSmith5159LosAngelez
JaneDo7729NewYork       |  JaneDoe7719NewYork
etc            

Кто-нибудь знает, есть ли простой известный сценарий или способ сделать это? пожалуйста :)

1 Ответ

1 голос
/ 25 мая 2020

Есть встроенный difflib, который может возвращать коэффициент схожести строк.

Затем я написал функцию, возвращающую строку с максимальным сходством, если это отношение схожести больше или равно 0,9 между двумя строками.

Существует небольшой ярлык для проверки совпадения первой буквы из двух строк. В противном случае расчет не выполняется. Эта идея отсюда: { ссылка }

И я предполагаю, что вы работаете в pandas, поэтому я добавил пример того, как заполнить pandas DataFrame результатами.

from difflib import SequenceMatcher

def similar(a, b):
    """ https://stackoverflow.com/a/17388505/42346 """
    return SequenceMatcher(None, a, b).ratio()

def max_similar_string(s, l):
    first_letter_match = [i for i in l if s[0] == i[0]]
    if len(first_letter_match):
        max_ratio = 0
        max_ratio_string = ''
        for i in l:
            ratio = similar(i,s)
            if ratio > max_ratio:
                max_ratio = ratio
                max_ratio_string = i
        if max_ratio >= 0.9:
            return (max_ratio_string,max_ratio)
    else:
        return (np.nan,np.nan)

l = ['JohnDSmith5159LosAngelez','JaneDoe7719NewYork']

df = pd.DataFrame({'s':['JohnSmith5159LosAngeles','JaneDo7729NewYork']}) 

for idx in df.index: 
    df.loc[idx,'similar'], df.loc[idx,'ratio'] = max_similar_string(df.loc[idx,'s'],l) 

Результат:

                         s                   similar     ratio
0  JohnSmith5159LosAngeles  JohnDSmith5159LosAngelez  0.936170
1        JaneDo7729NewYork        JaneDoe7719NewYork  0.914286
...