我需要对葡萄牙语字符串执行词干。为此,我使用nltk.word_tokenize()函数对字符串进行标记,然后单独插入每个单词。之后,我重建了字符串。它工作正常,但表现不佳。我怎样才能让它更快?字符串长度约为200万字。
tokenAux=""
tokens = nltk.word_tokenize(portugueseString)
for token in tokens:
tokenAux = token
tokenAux = stemmer.stem(token)
textAux = textAux + " "+ tokenAux
print(textAux)
抱歉英语不好,谢谢!
答案 0 :(得分:3)
string
是不可变的,所以如果字符串很长,每次更新字符串都不是好习惯。 link here解释了连接字符串和显示性能分析的各种方法。而且,由于迭代只进行一次,因此最好选择generator expression
而不是list comprehension
。有关详细信息,请查看discussion here 。相反,在这种情况下,将generator expression
与join
一起使用可能会有所帮助:
将my_text
用于长字符串:len(my_text) -> 444399
使用timeit
进行比较:
%%timeit
tokenAux=""
textAux=""
tokens = nltk.word_tokenize(my_text)
for token in tokens:
tokenAux = token
tokenAux = stemmer.stem(token)
textAux = textAux + " "+ tokenAux
结果:
1 loop, best of 3: 6.23 s per loop
将generator expression
与join
一起使用:
%%timeit
' '.join(stemmer.stem(token) for token in nltk.word_tokenize(my_text))
结果:
1 loop, best of 3: 2.93 s per loop
答案 1 :(得分:1)
String对象在Python中是不可变的。查看您的代码:
textAux = ""
for token in tokens:
# something important ...
textAux = textAux + " "+ tokenAux
每次在循环中创建新字符串并将其分配给textAux
变量。这效率不高。
我会将tokenAux
个元素存储在列表中,并在最后加入它们。参见示例:
tokenAux = [] # we declare list for storing tokens
tokens = nltk.word_tokenize(portugueseString)
for token in tokens:
tokenAux = token
tokenAux = stemmer.stem(token)
textAux.append(tokenAux) # we add new token into the resulting list
result = " ".join(textAux) # join list using space as separator
print(result)
比较表现并与我们分享:)
有用的链接:
答案 2 :(得分:0)
您可以将字符串作为文本文件读取,然后使用PySpark执行必要的操作以阻止每个单词。这将允许您并行执行操作。
您还可以使用multiprocessing module。