我有一个测向仪:
id text
1 This is a good sentence
2 This is a sentence with a number: 2015
3 This is a third sentence
我有一个文本清理功能:
^{pr2}$get_wordnet_pos()
这是:
def get_wordnet_pos(treebank_tag):
if treebank_tag.startswith('J'):
return wordnet.ADJ
elif treebank_tag.startswith('V'):
return wordnet.VERB
elif treebank_tag.startswith('N'):
return wordnet.NOUN
elif treebank_tag.startswith('R'):
return wordnet.ADV
else:
return wordnet.NOUN
我正在将extractFeatures()
应用于pandas列,并创建一个新列,结果如下:
df['cleanText'] = df['text'].apply(clean)
结果df:
id cleanText
1 good sentence
2 sentence number
3 third sentence
循环时间似乎呈指数增长。例如,使用%%timeit
,将其应用于5行,每次循环17毫秒。300行,每环路800ms。500行,每环1.26秒。在
我通过在函数之外实例化stops
和{
stops = set(stopwords.words('english'))
lem = WordNetLemmatizer()
def clean(text):
lettersOnly = re.sub('[^a-zA-Z]',' ', text)
tokens = word_tokenize(lettersOnly.lower())
tokens = [w for w in tokens if not w in stops]
tokensPOS = pos_tag(tokens)
tokensLemmatized = []
for w in tokensPOS:
tokensLemmatized.append(lem.lemmatize(w[0], get_wordnet_pos(w[1])))
clean = " ".join(tokensLemmatized)
return clean
在apply
行上运行%prun -l 10
得到了这个表:
672542 function calls (672538 primitive calls) in 2.798 seconds
Ordered by: internal time
List reduced from 211 to 10 due to restriction <10>
ncalls tottime percall cumtime percall filename:lineno(function)
4097 0.727 0.000 0.942 0.000 perceptron.py:48(predict)
4500 0.584 0.000 0.584 0.000 {built-in method nt.stat}
3500 0.243 0.000 0.243 0.000 {built-in method nt._isdir}
14971 0.157 0.000 0.178 0.000 {method 'sub' of '_sre.SRE_Pattern' objects}
57358 0.129 0.000 0.155 0.000 perceptron.py:250(add)
4105 0.117 0.000 0.201 0.000 {built-in method builtins.max}
184365 0.084 0.000 0.084 0.000 perceptron.py:58(<lambda>)
4097 0.057 0.000 0.213 0.000 perceptron.py:245(_get_features)
500 0.038 0.000 1.220 0.002 perceptron.py:143(tag)
2000 0.034 0.000 0.068 0.000 ntpath.py:471(normpath)
它看起来像是感知器标签,可以预见,占用了大量的资源,但我不知道如何精简它。另外,我不确定nt.stat
或{
如何更改函数或应用方法以提高性能?这个函数是Cython还是Numba的候选函数?在
我在这里看到的第一个明显的改进点是整个
get_wordnet_pos
函数应该可以简化为字典查找:相反,请从
^{pr2}$collections
包初始化defaultdict
:然后,您将按如下方式访问查找:
接下来,如果要在多个地方使用regex模式,可以考虑预编译它。你得到的加速没有那么多,但这一切都很重要。在
在函数内部,可以调用:
哦,如果你知道你的文本是从哪里来的,并且对你可能看到的和可能看不到的内容有一些了解,那么你可以预先编译一个字符列表,而使用
str.translate
,这比笨重的基于regex的替换快得多:此外,我想说
word_tokenize
是过度杀戮-你所做的就是去掉特殊字符,这样你就失去了word_tokenize
的所有好处,而这确实与标点符号等不同。你可以选择回到text.split()
。在最后,跳过
clean = " ".join(tokensLemmatized)
步骤。只需返回列表,然后在最后一步中调用df.applymap(" ".join)
。在我把基准测试留给你。在
相关问题 更多 >
编程相关推荐