我正在尝试使用数据集中的百万行来运行一个函数。
代码:
def nlkt(val):
val=repr(val)
clean_txt = [word for word in val.split() if word.lower() not in stopwords.words('english')]
nopunc = [char for char in str(clean_txt) if char not in string.punctuation]
nonum = [char for char in nopunc if not char.isdigit()]
words_string = ''.join(nonum)
return words_string
现在我正在使用 for 循环调用上述函数来运行数百万条记录。即使我在一个带有 24 核 cpu 和 88 GB Ram 的重量级服务器上,我看到循环花费了太多时间并且没有使用那里的计算能力
我像这样调用上面的函数
data = pd.read_excel(scrPath + "UserData_Full.xlsx", encoding='utf-8')
droplist = ['Submitter', 'Environment']
data.drop(droplist,axis=1,inplace=True)
#Merging the columns company and detailed description
data['Anylize_Text']= data['Company'].astype(str) + ' ' + data['Detailed_Description'].astype(str)
finallist =[]
for eachlist in data['Anylize_Text']:
z = nlkt(eachlist)
finallist.append(z)
当我们有几百万条记录时,上面的代码工作得很好,只是太慢了。它只是 excel 中的一个示例记录,但实际数据将在 DB 中,该数据库将运行数亿。有什么方法可以加快操作以更快地通过函数传递数据 - 而是使用更多的计算能力?
最佳答案
您的原创 nlkt()
每行循环 3 次。
def nlkt(val):
val=repr(val)
clean_txt = [word for word in val.split() if word.lower() not in stopwords.words('english')]
nopunc = [char for char in str(clean_txt) if char not in string.punctuation]
nonum = [char for char in nopunc if not char.isdigit()]
words_string = ''.join(nonum)
return words_string
此外,每次您调用
nlkt()
时,你一次又一次地重新初始化这些。stopwords.words('english')
string.punctuation
这些应该是全局性的。
stoplist = stopwords.words('english') + list(string.punctuation)
逐行处理:
val=repr(val)
我不确定你为什么需要这样做。但是您可以轻松地将列转换为
str
类型。这应该在您的预处理功能之外完成。希望这是不言自明的:
>>> import pandas as pd
>>> df = pd.DataFrame([[0, 1, 2], [2, 'xyz', 4], [5, 'abc', 'def']])
>>> df
0 1 2
0 0 1 2
1 2 xyz 4
2 5 abc def
>>> df[1]
0 1
1 xyz
2 abc
Name: 1, dtype: object
>>> df[1].astype(str)
0 1
1 xyz
2 abc
Name: 1, dtype: object
>>> list(df[1])
[1, 'xyz', 'abc']
>>> list(df[1].astype(str))
['1', 'xyz', 'abc']
现在转到下一行:
clean_txt = [word for word in val.split() if word.lower() not in stopwords.words('english')]
使用
str.split()
很尴尬,您应该使用适当的标记器。否则,您的标点符号可能会卡在前面的单词上,例如>>> from nltk.corpus import stopwords
>>> from nltk import word_tokenize
>>> import string
>>> stoplist = stopwords.words('english') + list(string.punctuation)
>>> stoplist = set(stoplist)
>>> text = 'This is foo, bar and doh.'
>>> [word for word in text.split() if word.lower() not in stoplist]
['foo,', 'bar', 'doh.']
>>> [word for word in word_tokenize(text) if word.lower() not in stoplist]
['foo', 'bar', 'doh']
同时检查
.isdigit()
应该一起检查:>>> text = 'This is foo, bar, 234, 567 and doh.'
>>> [word for word in word_tokenize(text) if word.lower() not in stoplist and not word.isdigit()]
['foo', 'bar', 'doh']
把你的一切放在一起
nlkt()
应该是这样的:def preprocess(text):
return [word for word in word_tokenize(text) if word.lower() not in stoplist and not word.isdigit()]
您可以使用
DataFrame.apply
:data['Anylize_Text'].apply(preprocess)
关于python - 为什么我的 NLTK 函数在处理 DataFrame 时很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47769818/