Fuzzywuzzy сопоставляет 2 столбца… скрипт продолжает работать

#python-3.x #string-matching #fuzzywuzzy

#python-3.x #сопоставление строк #fuzzywuzzy

Вопрос:

Я пытаюсь сопоставить 2 столбца из ~ 50.000 экземпляров с помощью Fuzzywuzzy. Столбец A (компании) содержит названия компаний с некоторыми опечатками. Столбец B (правильный) содержит правильные названия компаний.

Я пытаюсь сопоставить опечатки с правильными. При запуске моего сценария ниже ядро продолжает выполняться в течение нескольких часов и не выдает результата.

Есть идеи о том, как улучшить?

Большое спасибо!

Обновить ссылку на файлы:https://fromsmash.com/STLz.VEub2-ct

 import pandas as pd
from fuzzywuzzy import process, fuzz 
import matplotlib.pyplot as plt 

correct = pd.read_excel("correct.xlsx")
companies = pd.read_excel("companies2.xlsx")

actual_comp = []
similarity = []

for i in companies.Customers: 
    ratio = process.extract(i, correct.Correct, limit=1)
    actual_comp.append(ratio[0][0])
    similarity.append(ratio[0][1])
    
companies['actual_company'] = pd.Series(actual_comp)
companies['similarity'] = pd.Series(similarity) 

companies.head(10)
  

Ответ №1:

Есть пара вещей, которые вы можете изменить для повышения производительности:

  1. Используйте Rapidfuzz вместо Fuzzywuzzy, поскольку он реализует те же алгоритмы, но немного быстрее (я автор)

  2. Функции процесса предварительно обрабатывают все строки, которые вы им передаете (вводят их в нижний регистр, удаляют не буквенно-цифровые символы и обрезают пробелы). Прямо сейчас ваше время предварительной обработки correct.Correct len(companies.Customers) , которое требует много времени и может быть выполнено один раз перед циклом вместо этого

  3. Вы используете только наилучшее соответствие, поэтому лучше использовать process.extractOne вместо process.extract . Это более читаемо, а внутри extractOne rapidfuzz использует результаты предыдущего сравнения для повышения производительности

Следующий фрагмент реализует эти изменения для вашего кода. Имейте в виду, что вы все еще выполняете сравнения 50k ^ 2, поэтому, хотя это должно быть намного быстрее, чем ваше текущее решение, это все равно займет некоторое время.

 import pandas as pd
from rapidfuzz import process, fuzz, utils
import matplotlib.pyplot as plt 

correct = pd.read_excel("correct.xlsx")
companies = pd.read_excel("companies2.xlsx")

actual_comp = []
similarity = []

company_mapping = {company: utils.default_process(company) for company in correct.Correct}

for customer in companies.Customers:
    _, score, comp = process.extractOne(
        utils.default_process(customer),
        company_mapping,
        processor=None)
    actual_comp.append(comp)
    similarity.append(score)
    
companies['actual_company'] = pd.Series(actual_comp)
companies['similarity'] = pd.Series(similarity) 

companies.head(10)
  

Из интереса я выполнил быстрый тест, вычисляющий среднее время выполнения при использовании ваших наборов данных. На моем компьютере для каждого поиска требуется около 1 секунды с этим решением (таким образом, в общей сложности около 4,7 часов), в то время как ваше предыдущее решение занимало около 55 секунд на поиск (таким образом, в общей сложности около 10,8 дней).

Комментарии:

1. Огромное спасибо! Я попытался установить с помощью pip install, но все равно получаю эту ошибку: «ImportError: ошибка загрузки DLL при импорте fuzz: указанный модуль не найден».

2. В Windows необходимо установить распространяемый C 19: support.microsoft.com/en-us/help/2977003 /…

3. Спасибо @maxbachmann . Должен ли я где-то определять ‘utils’? Ошибка имени: имя ‘utils’ не определено

4. Это часть библиотеки. В моем ответе он импортирован из rapidfuzz

5. Еще раз спасибо, мой плохой! Однако теперь он запущен, результат показывает «NaN» как для компании, так и для сходства… Для упрощения ссылки я добавил два файла в WeTransfer в исходном сообщении