我正在尝试从许多(100k)预先处理的文本文件中删除所有非英语单词(porter提取并小写,删除所有非a-z字符)。我已经并行化了该过程以加快处理速度,但是它仍然非常缓慢。有没有更有效的方法在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)
答案 0 :(得分:3)
您正在检查somthing in otherthing
-并且您的otherthing
是一个列表。
列表非常适合存储内容,但是查找列表中的“ does x in”会花费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):最坏的情况:您的单词是列表中20万个单词的最后一个,然后您检查了整个列表-需要进行200k个检查。
O(1):查找时间是恒定的,无论数据结构中有多少项,检查它的时间都需要相同的时间。要获得此好处,set
具有更多的优点。复杂的存储解决方案,需要更多的内存(然后是列表)才能在查询中表现出色。
编辑:最糟糕的情况是 not 在集合/列表中找不到单词:
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