Быстрый (э) способ проверить, является ли слово английским, сравнивая его с белым списком английских слов? - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь удалить все неанглийские слова из многих (100k) предварительно обработанных текстовых файлов (с использованием переносчика и в нижнем регистре, отбрасывает все символы, отличные от az).Я уже распараллелил процесс, чтобы ускорить процесс, но он все еще мучительно медленный.Есть ли более эффективный способ сделать это в Python?

englishwords = list(set(nltk.corpus.words.words()))
englishwords = [x.lower() for x in list(englishwords)]
englishwords = [ps.stem(w) for w in englishwords]
# this step takes too long:
shareholderletter= ' '.join(w for w in nltk.wordpunct_tokenize(shareholderletter) if w in englishwords)

1 Ответ

0 голосов
/ 24 октября 2018

Вы проверяете на somthing in otherthing - и ваш otherthing является списком.

Списки хороши для хранения вещей, но поиск "делает х в" ваш список занимает O(n).

Используйте взамен set, который понижает поиск до O(1) и , он уничтожает любые дубликаты, так что ваш базовый размер вещей также можно искать по каплям, если у вас есть дубликаты.

Если ваш набор впоследствии не изменится, перейдите и используйте frozenset - который является неизменным.

Чтение: Документирование наборов

Если вы будете следовать предложению @DeepSpace и использовать операции над множествами, вы получите еще большую производительность:

s = set( t.lower().strip() for t in ["Some","text","in","set"])

t = set("Some text in a string that holds other words as well".lower().split())

print ( s&t )  # show me all things that are in both sets (aka intersection)

Вывод:

set(['text', 'some', 'in'])

См. операции над множествами


O (n): наихудший регистр: ваше слово является последним из 200 тыс. Слов в вашем списке, и вы проверяете весь список - что требует 200 тыс. Проверок.

O (1): время поиска является постоянным, независимо от того, сколько элементов в вашей структуре данных, требуется одинаковое количество времени, чтобы проверить, входит ли оно. Чтобы получить это преимущество, set имеет более сложное решение для хранения, которое требует чуть большепамять (затем список), чтобы работать так хорошо при поисках.


Редактировать: худший случайсценарий для не поиска слова внутри набора / списка:

import timeit

setupcode = """# list with some dupes
l = [str(i) for i in range(10000)] + [str(i) for i in range(10000)] + [str(i) for i in range(10000)]
# set of this list
s = set( l )
"""

print(timeit.timeit("""k = "10000" in l """,setup = setupcode, number=100))
print(timeit.timeit("""k = "10000" in s """,setup = setupcode, number=100))

0.03919574100000034    # checking 100 times if "10000" is in the list
0.00000512200000457    # checking 100 times if "10000" us in the set
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...