Python统计指定词库在大量评论中出现频次效率低,如何优化?
性能瓶颈分析
你当前代码的核心问题是时间复杂度过高:在140万目标词的循环中每次全量扫描所有评论,总计算量达到140万*2.5万=3.5e10次,同时str.contains默认启用正则匹配,额外增加了单步操作开销,完全不适合大规模数据场景。
另外补充:你当前代码统计的是包含该词的评论条数,不是词的总出现次数,单条评论中同一个词出现多次只会计为1次,如果需要统计总出现次数,原有逻辑本身就需要调整。
优化方案
方案1:反向统计(优先推荐,时间复杂度骤降)
不要拿词去搜评论,反过来先拆分所有评论的单词做统计,再和目标词库取交集,仅需要遍历2.5万条评论1次,再遍历词频统计结果1次,时间复杂度直接降到O(评论总词数 + 目标词数),性能提升千倍以上。
代码示例:
from collections import Counter import re # 先把目标词转成集合,实现O(1)速度判断是否属于目标词库 word_set = set([w.lower() for w in listOfWords]) # 自定义统计逻辑,可根据需求调整分词规则 def count_review_words(review_series): cnt = Counter() for review in review_series: # 按整词拆分,自动过滤标点符号,\b代表单词边界 words = re.findall(r'\b\w+\b', review) # 仅统计目标词库内的词 cnt.update(w for w in words if w in word_set) return dict(cnt) positiveReviews = reviews[labels == 'positive'].str.lower() negativeReviews = reviews[labels == 'negative'].str.lower() countsForPositive = count_review_words(positiveReviews) countsForNegative = count_review_words(negativeReviews) # 如果需要补全词库中出现次数为0的词,可加以下逻辑 for word in listOfWords: countsForPositive.setdefault(word.lower(), 0) countsForNegative.setdefault(word.lower(), 0)
方案2:Aho-Corasick多模式匹配(适合子串匹配场景)
如果你的需求不是整词匹配,只要评论中出现词的子串就算命中,可以用AC自动机一次性加载所有目标词为匹配模式,单趟扫描所有评论就能拿到所有词的出现次数,比单模式循环匹配快100倍以上。
依赖安装:pip install pyahocorasick
代码示例:
import ahocorasick # 构建AC自动机 def build_ac_automaton(word_list): ac = ahocorasick.Automaton() for idx, word in enumerate(word_list): ac.add_word(word.lower(), (idx, word.lower())) ac.make_automaton() return ac ac = build_ac_automaton(listOfWords) def count_by_ac(review_series): cnt = {w.lower():0 for w in listOfWords} for review in review_series: for end_idx, (_, word) in ac.iter(review): cnt[word] += 1 return cnt countsForPositive = count_by_ac(positiveReviews) countsForNegative = count_by_ac(negativeReviews)
额外调优细节
- 如果你坚持用原有逻辑统计评论命中次数,可给
str.contains加regex=False参数,单步匹配速度能提升30%以上,但本质还是O(M*N)复杂度,仅适合小数据量场景。 - 评论量更大的情况下,可以把评论列表拆分成多段用多进程并行统计,进一步压缩耗时。
内容的提问来源于stack exchange,提问作者Arzanish Sarwar
相关产品推荐
相关产品推荐

