Самый быстрый способ внести список слов в белый список другим набором, сохраняя порядок слов - PullRequest
1 голос
/ 28 мая 2020

У меня есть список слов типа words = ['a', 'spam', 'an', 'eggs', 'the', 'foo', 'and', 'bar'].

И я хочу исключить некоторые слова (стоп-слова), определенные в другом списке, или установить stop_words = ['a', 'an', 'the', 'and'].

Что такое самый быстрый способ сделать это, а также сохранить порядок исходного списка? Я пробовал использовать set() или даже SortedSet(). Но это все равно не помогает, слова по-прежнему отличаются от исходного порядка.

r1 = set(words) - set(stop_words)
r2 = SortedSet(words) - SortedSet(stop_words)

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

r3 = [w for w in words if w not in stop_words]

Ответы [ 2 ]

3 голосов
/ 28 мая 2020

Вы можете использовать set вместо stop_words, а затем пройти по исходному списку:

stop_words = set(stop_words)
result = [w for w in words if w not in stop_words]
1 голос
/ 28 мая 2020

Предоставление небольшого теста с более длинным списком слов из Шекспира (длина 202651 слова) и векторизованным решением:

text = requests.get('https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt').text

words_list = text.lower().split()
words_array = np.array(words_list)
stop_words = ['a', 'an', 'the', 'and']
set_stopwords = set(stop_words)

def numpy_filter():
    """Taking a Numpy array and returning a filtered array"""
    return words_array[np.isin(words_array,stop_words,invert=True)]

def numpy_list_filter():
    """Taking a Numpy array and returning a filtered list"""
    return words_array[np.isin(words_array,stop_words,invert=True)].tolist()

def list_filter():
    """Iterating over a list filtering by elements included in a list"""
    return [w for w in words_list if w not in stop_words]

def list_set_filter():
    """Iterating over a list filtering by elements included in a set"""
    return [w for w in words_list if w not in set_stopwords]

Вот результаты с моим двухъядерным процессором Intel Core 2,5 ГГц i7 в том порядке, в котором функции были определены выше:

12.6 ms ± 378 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

31.6 ms ± 1.27 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

24.1 ms ± 4.98 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

11.7 ms ± 265 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Самый быстрый вариант среди опробованных - это тот, который предложил @a_guest. Это остается верным, даже если вы увеличите список в 100 раз. Как видите, преобразование stop_words в набор приводит к значительному повышению производительности. Numpy также довольно быстр, но если вам нужно преобразовать его обратно в список в конце, связанные с этим накладные расходы сделают его самым медленным методом среди тех, которые пробовали.

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