Вы должны повторно назначить результат замены, например:
sentence = sentence.replace("and", " ");
Имейте в виду, что класс String
является неизменным , а это означает, что все его методы возвращают новую строку и никогда не изменяют исходную строку на месте, поэтому результат вызова метода в экземпляре String
должен быть присвоен переменной или использоваться немедленно для изменения эффект.
Попробуйте кэшировать объект стоп-слов, как показано ниже. Создание этого при каждом вызове функции кажется узким местом.
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 раз.
Используйте регулярное выражение, чтобы удалить все слова, которые не совпадают:
import re
pattern = re.compile(r'\b(' + r'|'.join(stopwords.words('english')) + r')\b\s*')
text = pattern.sub('', text)
Это, вероятно, будет намного быстрее , чем зацикливание, особенно для больших строк ввода.
Если последнее слово в тексте будет удалено из-за этого, у вас может быть завершающий пробел. Я предлагаю разобраться с этим отдельно.
Во-первых, вы создаете стоп-слова для каждой строки. Создайте это один раз. Сет действительно был бы великолепен здесь.
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> См. Тист Хэд о том, почему s.split()
действительно быстро.
Наконец, сделайте такую работу параллельно (удаляя стоп-слова в 6-метровых строках). Это совсем другая тема.
Извините за поздний ответ. Будет полезным для новых пользователей.
Использовать этот словарь для очень быстрого поиска (время = 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])