通过另一组保持单词顺序将单词列表列入白名单的最快方法



我有像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]

您可以使用set进行stop_words,然后浏览原始列表:

stop_words = set(stop_words)
result = [w for w in words if w not in stop_words]

通过莎士比亚的较长单词列表(长度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]

以下是我的 2,5 GHz 双核英特尔酷睿 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 也非常快,但如果最后需要将其转换回列表,所涉及的开销使其成为尝试的方法中最慢的方法。

最新更新