Проблема:
У меня есть список слов длиной 48 000, и я пытаюсь сгруппировать возможные 4 слова (если они есть, но меньше), которые ближе всего друг к другу. Я получаю помощь от модуля difflib
.
У меня было 2 способа сделать это в моей голове. Получите 4 ближайших совпадения, используя difflib.get_close_matches()
, или составьте декартово произведение из списка слов и получите оценки по каждому кортежу из списка товаров.
У меня есть код, который работает для небольших списков, но когда длина списка увеличивается (в моем случае 48k), это занимает огромное количество времени. Я ищу масштабируемое решение для этой проблемы.
Код для воспроизведения такого списка:
import random , string , itertools , difflib
from functools import partial
N = 10
random.seed(123)
words = [''.join(random.choice(string.ascii_lowercase) for i in range(5)) for j in range(10)]
Мои попытки:
1: Создана функция, которая будет возвращать счет после создания декартового произведения. После этого я могу сгруппировать по первому элементу и взять верхний n по своему желанию.
def fun(x) : return difflib.SequenceMatcher(None,*x).ratio()
products = list(itertools.product(words,words))
scores = list(map(fun,products))
2: Функция, которая напрямую дает наилучшее n (4) совпадений
f = partial(difflib.get_close_matches , possibilities = words , n=4 , cutoff = 0.4)
matches = list(map(f,words)) #this gives 4 possible matches if presentwords
Это также ожидаемый результат.
Оба работают для небольшого списка, но по мере увеличения размера списка это занимает очень много времени. Поэтому я попытался прибегнуть к многопроцессорной обработке:
Попытка многопроцессорной обработки 1:
Сохранить первую функцию (fun
) при попытке 1 в файле py, а затем импортировать ее
import multiprocessing
pool = multiprocessing.Pool(8)
import fun
if__name__ == '__main__':
score_mlt_pr = pool.map(fun.fun, products ) #products is the cartesian product same as attempt 1
scores_mlt = list(score_mlt_pr)
попытка многопроцессорной обработки 2:
Использование того же f
, что и попытка 2 ранее, но с пулом:
close_matches = list(pool.map(f,words))
с многопроцессорной обработкой время, затрачиваемое на сокращение, но составляет около 1 часа для комбинации 1000 * 48000 слов.
Надеюсь, я мог бы привести наглядный пример своей проблемы. Пожалуйста, посоветуйте, как я могу ускорить мой код.