【问题标题】:Python | Jupyter Notebook - NLTK function slow when checking for words蟒蛇 | Jupyter Notebook - 检查单词时 NLTK 功能变慢
【发布时间】:2021-11-26 08:02:42
【问题描述】:

我正在尝试使用 NLTK 清理我的数据集,但我遇到了一些麻烦,因为它需要很长时间才能完成。我确实有一个非常大的数据集,包含超过 20000 多行文本。

我正在运行的代码如下所示:

from nltk.corpus import words
nltk.download('words')
gibberishBody = []

for x in bodyStopWords:
    if x in words.words():
        gibberishBody.append(x)
print(gibberishBody)

bodyStopWords 是 pandas.core.series.Series 数据类型。

有人对优化脚本速度有什么建议吗?

【问题讨论】:

  • 请以代码sn -p @Ashish的形式添加一小部分数据

标签: python optimization nlp nltk


【解决方案1】:

在您的示例中,words.words() 返回大量英语单词。通过in 检查成员资格对于列表来说很慢(线性)。也就是说,要检查某个单词 x 是否在您的单词列表中,必须将 x 与列表中的每个元素进行比较。

相反,您可以使用set 来加快该过程,因为它具有恒定的时间查找*。请尝试以下操作:

from nltk.corpus import words
nltk.download('words')
gibberishBody = []
my_words = set(words.words())
for x in bodyStopWords:
    if x in my_words:
        gibberishBody.append(x)
print(gibberishBody)

* 从技术上讲,恒定时间只是在预期中,但这已经足够了。

【讨论】:

  • 感谢您的快速回复!测试时我得到这个输出:code ---------------------------------------- ---------------------------------- TypeError Traceback(最近一次调用最后一次) in 8 9 for x in bodyPre: ---> 10 if x in my_words: 11 gibberishBody.append(x) 12 print(gibberishBody) code
  • 恐怕在这种格式中我不确定错误是什么。但请注意,代码原样不可运行,因为 bodyStopWords 未定义。
  • 也许 bodyStopWords 是一个列表列表?在这种情况下,这将不起作用,因为列表不能被散列,因此不能用于在集合中查找(因为 python set 是一个散列表)。
【解决方案2】:

这可能会改善问题。 words.words() 返回一个列表。每次调用 words() 函数时,都必须构建该列表可能。尽管如此,在列表中使用 in 关键字比在集合中使用时要慢得多。鉴于列表中的所有单词都是唯一的,您可以按如下方式重新排列代码:

from nltk.corpus import words
from pandas import DataFrame
import random
import time

WL = words.words() # get the word list
print(f'Word list contains {len(WL)} words')
WS = set(WL) # convert to a set
NW = min(20_000, len(WL)) # not really necessary as the word list is known to contain over 200k words
bodyStopWords = DataFrame([random.choice(WL) for _ in range(NW)])[0] # get a Series representation
print(f'{NW} random stopwords chosen')
s = time.perf_counter() # note start time
gibberishBody = [x for x in bodyStopWords if x in WS] # build the body
e = time.perf_counter() # note end time
print(f'{e-s:.4f}s')

这是对我原始答案的重写,包括熊猫系列并展示了性能特征。在我的机器上,gibberishBody 列表是在 0.0051 秒内构建的

【讨论】:

  • 感谢您的回复! code----------------------------------------------- ---------------------------- TypeError Traceback (最近一次调用最后) in 8 W = set(words.words()) 9 ---> 10 gibberishBody = [x for x in bodyPre if x in W] 11 12 print(gibberishBody) in (. 0) 8 W = set(words.words()) 9 ---> 10 gibberishBody = [x for x in bodyPre if x in W] 11 12 print(gibberishBody) TypeError: unhashable type: 'list' code
  • 如果 bodyStopWords 是范围内的可迭代对象,此代码将在 Python 3.9.9 中完美运行。显然它不能按原样运行,但您在问题中提供的代码也不能运行!
猜你喜欢
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 2018-08-19
  • 2020-11-09
  • 2022-10-25
  • 1970-01-01
相关资源
最近更新 更多