You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python循环统计文本单词出现次数性能优化求助

优化文本单词出现次数统计的性能方案

原代码循环遍历单词列表,每次对整个DataFrame的Text列调用str.count,时间复杂度为O(M*N)(M是文本行数,N是单词列表长度),重复遍历数据集导致效率极低,尤其是单词列表较长时。以下是三种高效优化方案:

方案一:正则批量匹配+分组统计

利用正则一次性匹配所有目标单词,再通过分组统计次数,避免多次遍历数据集。

import pandas as pd
import re

# 假设已有df和wordlist
wordlist = ['i','love','David','Mary']

# 统一大小写,避免大小写不匹配问题
wordlist_lower = [word.lower() for word in wordlist]
df['Text_lower'] = df['Text'].str.lower()

# 构建正则模式:匹配整个单词(若需子串匹配则去掉\b)
pattern = r'\b(' + '|'.join(re.escape(word) for word in wordlist_lower) + r')\b'
# 提取所有匹配的单词
matches = df['Text_lower'].str.extractall(pattern)[0]
# 按原行索引和单词分组统计次数
counts = matches.groupby([matches.index.get_level_values(0), 0]).size().unstack(fill_value=0)
# 合并到原DataFrame
df = df.join(counts)
# 可选:删除临时列
df.drop('Text_lower', axis=1, inplace=True)

说明:

  • \b用于匹配完整单词,避免子串误匹配(如'love'不会匹配'loved');若需统计子串出现次数,可移除\b。
  • re.escape处理单词中的特殊字符,避免正则语法错误。

方案二:使用CountVectorizer向量化统计

借助sklearn的CountVectorizer进行批量词频统计,底层为向量化操作,效率极高。

import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer

# 假设已有df和wordlist
wordlist = ['i','love','David','Mary']

# 统一大小写
wordlist_lower = [word.lower() for word in wordlist]
df['Text_lower'] = df['Text'].str.lower()

# 初始化向量器,指定目标单词列表
vectorizer = CountVectorizer(vocabulary=wordlist_lower, token_pattern=r'\b\w+\b')
# 转换文本得到词频矩阵
count_matrix = vectorizer.fit_transform(df['Text_lower'])
# 转换为DataFrame并合并
count_df = pd.DataFrame(
    count_matrix.toarray(),
    columns=vectorizer.get_feature_names_out(),
    index=df.index
)
df = df.join(count_df)
df.drop('Text_lower', axis=1, inplace=True)

说明:

  • token_pattern=r'\b\w+\b'确保匹配完整单词,若需子串统计可调整或移除该参数。
  • 该方法适合单词列表较长的场景,性能远优于循环遍历。

方案三:拆分文本+Explode分组统计

通过拆分文本为单词列表,展开后过滤目标单词再分组计数,逻辑直观。

import pandas as pd

# 假设已有df和wordlist
wordlist = ['i','love','David','Mary']

# 统一大小写
wordlist_lower = [word.lower() for word in wordlist]
df['Text_lower'] = df['Text'].str.lower()

# 拆分文本为单词列表(按非字母字符分割)
df['words'] = df['Text_lower'].str.split(r'\W+')
# 展开每个单词为单独行
exploded = df.explode('words')
# 过滤出目标单词
filtered = exploded[exploded['words'].isin(wordlist_lower)]
# 按原行索引和单词统计次数
counts = filtered.groupby([filtered.index, 'words']).size().unstack(fill_value=0)
# 合并到原DataFrame
df = df.join(counts)
# 删除临时列
df.drop(['Text_lower', 'words'], axis=1, inplace=True)

注意事项:

  • 若文本中有连续非字母字符,split(r'\W+')会自动处理,避免空字符串。
  • 该方法内存占用略高,适合文本长度适中的场景。

内容的提问来源于stack exchange,提问作者foy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:25:18