Более быстрый способ удаления стоп-слов в Python

Вы должны повторно назначить результат замены, например:

 sentence = sentence.replace("and", " ");

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

29
задан mchangun 24 October 2013 в 08:13
поделиться

4 ответа

Попробуйте кэшировать объект стоп-слов, как показано ниже. Создание этого при каждом вызове функции кажется узким местом.

    from nltk.corpus import stopwords

    cachedStopWords = stopwords.words("english")

    def testFuncOld():
        text = 'hello bye the the hi'
        text = ' '.join([word for word in text.split() if word not in stopwords.words("english")])

    def testFuncNew():
        text = 'hello bye the the hi'
        text = ' '.join([word for word in text.split() if word not in cachedStopWords])

    if __name__ == "__main__":
        for i in xrange(10000):
            testFuncOld()
            testFuncNew()

Я запустил это через профилировщик: python -m cProfile -s cumulative test.py . Соответствующие строки размещены ниже.

Совокупное время nCalls

10000 7,723 words.py:7(testFuncOld)

10000 0,140 words.py:11(testFuncNew)

Итак, кэшируем экземпляр стоп-слов дает ускорение в ~ 70 раз.

73
ответ дан Andy Rimmer 24 October 2013 в 08:13
поделиться

Используйте регулярное выражение, чтобы удалить все слова, которые не совпадают:

import re
pattern = re.compile(r'\b(' + r'|'.join(stopwords.words('english')) + r')\b\s*')
text = pattern.sub('', text)

Это, вероятно, будет намного быстрее , чем зацикливание, особенно для больших строк ввода.

Если последнее слово в тексте будет удалено из-за этого, у вас может быть завершающий пробел. Я предлагаю разобраться с этим отдельно.

12
ответ дан Alfe 24 October 2013 в 08:13
поделиться

Во-первых, вы создаете стоп-слова для каждой строки. Создайте это один раз. Сет действительно был бы великолепен здесь.

forbidden_words = set(stopwords.words('english'))

Позже, избавьтесь от [] внутри join. Вместо этого используйте генератор.

' '.join([x for x in ['a', 'b', 'c']])

заменить на

' '.join(x for x in ['a', 'b', 'c'])

Следующее, с чем нужно иметь дело, это заставить .split() возвращать значения вместо возврата массива. Я считаю, что regex будет хорошей заменой здесь. См. Тист Хэд о том, почему s.split() действительно быстро.

Наконец, сделайте такую ​​работу параллельно (удаляя стоп-слова в 6-метровых строках). Это совсем другая тема.

4
ответ дан Community 24 October 2013 в 08:13
поделиться

Извините за поздний ответ. Будет полезным для новых пользователей.

  • Создать словарь стоп-слов с использованием библиотеки коллекций
  • Использовать этот словарь для очень быстрого поиска (время = O (1)), а не делать это в списке (время = O (стоп-слова) ))

    from collections import Counter
    stop_words = stopwords.words('english')
    stopwords_dict = Collections.counter(stop_words)
    text = ' '.join([word for word in text.split() if stopwords_dict[word]==0])
    
0
ответ дан Gulshan Jangid 24 October 2013 в 08:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: