Как сделать эффективный строковый фильтр в Python? - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть два объекта списка: wiki_text и corpus. wiki_text состоит из небольших фраз, а корпус состоит из длинных предложений.

wiki_text = ['never ending song of love - ns.jpg',
 'ecclesiological society',
 "1955-56 michigan wolverines men's basketball team",
 'sphinx strix',
 'petlas',
 '1966 mlb draft',
 ...]

corpus = ['Substantial progress has been made in the last twenty years',
          'Patients are at risk for prostate cancer.',...]

Моя цель - создать фильтр, который может отфильтровывать элементы в wiki_text, который является подстрокой элементов в корпусе. Например, если «экклезиологическое общество» существует как часть предложения в корпусе, оно должно быть сохранено в конечном результате. Окончательный результат должен быть подмножеством исходного wiki_text. Следующий код - это то, что я использовал раньше:

def wiki_filter(wiki_text, corpus):
    result = []
    for i in wiki_text:
        for e in corpus:
            if i in e:
                result.append(i)
                break
    return result

Однако, учитывая длину wiki_text и корпус (каждый> 10 миллионов). Эта функция работала очень долго. Есть ли лучший способ решить эту проблему?

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

Чтобы сделать это действительно быстро, я бы предложил немного неортодоксальный подход, а именно использование Lucene (PyLucene, если вы вынуждены использовать только Python).

Apache LuceneTM - это высокопроизводительный, полнофункциональный текстовый поиск Библиотека движка написана полностью на Java. PyLucene - это расширение Python для доступа к Java LuceneTM. Его цель чтобы позволить вам использовать текстовое индексирование и поиск Lucene возможности от Python.

Вот как бы я это сделал: Индексируйте корпусные предложения, каждое предложение в отдельной записи. Затем, используя функцию поиска Lucene, ищите каждую из фраз в своем вики-тексте, используя строковый запрос.

Теперь этот подход не самый простой и самый простой в использовании, но он будет одним из самых быстрых, на мой взгляд. Вы, вероятно, сможете выполнить миллионы запросов (фраз wiki_text) в миллионах записей (корпус) за считанные минуты. Так что, если решение flashctext @coldspeed удовлетворяет вашим потребностям, сделайте это, в противном случае, попробуйте Lucene!

0 голосов
/ 07 сентября 2018

Каким образом здесь может работать движок регулярных выражений? Вы можете попробовать

import re
re.findall('|'.join(wiki_text),'\n'.join(corpus))
0 голосов
/ 07 сентября 2018

Давайте посмотрим, может ли flashtext помочь здесь.

Сначала pip install flashtext, а затем создайте объект KeywordProcessor и вызовите extract_keywords, чтобы отфильтровать ваши строки.

from flashtext import KeywordProcessor
keyword_processor = KeywordProcessor()
for w in wiki_text:
    keyword_processor.add_keyword(w)

filtered_corpus = [c for c in corpus if keyword_processor.extract_keywords(c)]

К сожалению, API flashtext пока не имеет метода "has_keyword", поэтому вам необходимо проверить достоверность временного списка, который возвращает extract_keywords, а затем впоследствии отбросить его. Если вы хотите, вы можете внести свой вклад в проект на GitHub.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...