Найти строку нечеткого соответствия в списке с соответствующим значением строки и их количеством - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть один список A. Как показано ниже.

A = ['vikash','vikas','Vinod',Vikky','Akash','Vinodh','Sachin','Salman,'Ajay','Suchin','Akash','vikahs']

Я хочу сопоставить каждый элемент в списке с каждым элементом и найти нечеткие совпадающие строки каждого элемента с коэффициентом соответствия 90% или выше и считать подходящих элементов.

Мой результат должен быть таким, как показано ниже во фрейме данных.

string  Matching strings count
===============================
Vikash  vikas,vikahs      2
vikas   vikash,vikahs     2
vinod   vinodh            1
Vikky                     0
Akash   Akash             1
...
..
Vikahs vikash,vikas       2

Может ли кто-нибудь помочь мне добиться этого, поскольку я новичок в python?

Спасибо

1 Ответ

0 голосов
/ 08 апреля 2020

Это можно реализовать с помощью FuzzyWuzzy следующим образом:

import pandas as pd
from fuzzywuzzy import fuzz

elements = ['vikash', 'vikas', 'Vinod', 'Vikky', 'Akash', 'Vinodh', 'Sachin', 'Salman', 'Ajay', 'Suchin', 'Akash', 'vikahs']

results = [[name, [], 0] for name in elements]

for (i, element) in enumerate(elements):
    for (j, choice) in enumerate(elements[i+1:]):
        if fuzz.ratio(element, choice) >= 90:
            results[i][2] += 1
            results[i][1].append(choice)
            results[j+i+1][2] += 1
            results[j+i+1][1].append(element)

data = pd.DataFrame(results, columns=['name', 'duplicates', 'duplicate_count'])

В качестве альтернативы я написал библиотеку RapidFuzz, которая работает быстрее, возвращая те же результаты, что и FuzzyWuzzy, и может быть реализован следующим образом:

import pandas as pd
from rapidfuzz import fuzz

elements = ['vikash', 'vikas', 'Vinod', 'Vikky', 'Akash', 'Vinodh', 'Sachin', 'Salman', 'Ajay', 'Suchin', 'Akash', 'vikahs']

results = [[name, [], 0] for name in elements]

for (i, element) in enumerate(elements):
    for (j, choice) in enumerate(elements[i+1:]):
        if fuzz.ratio(element, choice, score_cutoff=90, preprocess=False):
            results[i][2] += 1
            results[i][1].append(choice)
            results[j+i+1][2] += 1
            results[j+i+1][1].append(element)

data = pd.DataFrame(results, columns=['name', 'duplicates', 'duplicate_count'])

Я провел быстрый тест, чтобы показать разницу во времени выполнения между двумя на 1000 запусков каждый:

# FuzzyWuzzy
0.13835792080499232

# RapidFuzz
0.03843669104389846

Вывод обоих из них это:

      name        duplicates  duplicate_count
0   vikash           [vikas]                1
1    vikas  [vikash, vikahs]                2
2    Vinod          [Vinodh]                1
3    Vikky                []                0
4    Akash           [Akash]                1
5   Vinodh           [Vinod]                1
6   Sachin                []                0
7   Salman                []                0
8     Ajay                []                0
9   Suchin                []                0
10   Akash           [Akash]                1
11  vikahs           [vikas]                1
...