我有像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]发布于 2020-05-28 16:38:18
提供更长的莎士比亚单词列表(长度为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也非常快,但是如果您需要在最后将它转换回列表,所涉及的开销使它成为尝试过的方法中最慢的方法。
发布于 2020-05-28 14:26:01
您可以将set用于stop_words,然后遍历原始列表:
stop_words = set(stop_words)
result = [w for w in words if w not in stop_words]https://stackoverflow.com/questions/62067109
复制相似问题