如何用Pandas无循环实现CountVectorizer生成DataFrame词频统计新列
高效实现每行文本单词计数(替代for循环)
嘿,你的问题我太熟悉了——用for循环逐行处理DataFrame文本确实会在数据量大的时候拖慢速度,咱们换用Pandas的向量化操作结合CountVectorizer来解决,效率会提升一大截!
思路解析
核心是批量处理所有文本,避免逐行循环的冗余操作:
- 用
CountVectorizer一次性拟合所有review文本,生成全局词汇表并转换为词频矩阵 - 将词频矩阵转为结构化DataFrame,每行对应原数据的一行,列是单词,值是对应出现次数
- 把每行的词频数据转换成你需要的
{单词:次数}字典格式
完整代码示例
import pandas as pd from sklearn.feature_extraction.text import CountVectorizer # 模拟你的数据集(替换成你实际的products DataFrame) data = { 'review': [ 'Food was Awesome', 'A favorite in our house! A favorite favorite', '' # 模拟空文本的边界情况 ] } products = pd.DataFrame(data) # 初始化CountVectorizer:如果需要统一单词大小写,设lowercase=True;否则保持False保留原格式 count_vect = CountVectorizer(lowercase=False) # 批量转换所有review文本为词频稀疏矩阵(这一步是效率提升的关键) word_count_matrix = count_vect.fit_transform(products['review']) # 将稀疏矩阵转为结构化DataFrame,列是单词,行对应原数据行 word_freq_df = pd.DataFrame( word_count_matrix.toarray(), columns=count_vect.get_feature_names_out() ) # 把每行转换为{单词:次数}的字典(只保留次数>0的单词,避免冗余的0值) products['word_count'] = word_freq_df.apply( lambda row: row[row > 0].to_dict(), axis=1 ) # 查看最终结果 print(products)
输出结果示例
review word_count 0 Food was Awesome {'Food': 1, 'Awesome': 1, 'was': 1} 1 A favorite in our house! A favorite favorite {'A': 2, 'favorite': 3, 'in': 1, 'our': 1, 'house': 1} 2 {}
为什么比你的原代码快?
你的原代码在循环里逐行调用fit_transform,这意味着每次循环都要重新拟合词汇表,做大量重复工作。而我们的方案:
- 只做一次全局
fit,一次性生成整个数据集的词汇表 - 用
sklearn优化过的批量转换生成词频矩阵,远快于逐行处理 - 最后用Pandas的
apply向量化操作,比原生for循环效率高很多
额外优化提示
如果你的review列包含标点符号,建议先做预处理(比如用str.replace去掉标点),这样单词计数会更准确:
# 示例:去掉所有标点符号 products['clean_review'] = products['review'].str.replace(r'[^\w\s]', '', regex=True) # 后续用clean_review列进行词频统计即可
内容的提问来源于stack exchange,提问作者Akshay
相关产品推荐
相关产品推荐

