我想计算文本文件中所有单词的频率。
>>> countInFile('test.txt')
应该返回 {'aaa':1, 'bbb': 2, 'ccc':1}
如果目标文本文件是这样的:
# test.txt
aaa bbb ccc
bbb
我在 一些帖子 之后用纯 python 实现了它。但是,我发现由于文件很大(> 1GB),纯 python 方法是不够的。
我认为借用sklearn的力量是一个候选。
如果您让 CountVectorizer 计算每一行的频率,我想您将通过对每一列求和来获得单词频率。但是,这听起来有点间接。
使用 python 计算文件中单词的最有效和最直接的方法是什么?
更新
我的(非常慢)代码在这里:
from collections import Counter
def get_term_frequency_in_file(source_file_path):
wordcount = {}
with open(source_file_path) as f:
for line in f:
line = line.lower().translate(None, string.punctuation)
this_wordcount = Counter(line.split())
wordcount = add_merge_two_dict(wordcount, this_wordcount)
return wordcount
def add_merge_two_dict(x, y):
return { k: x.get(k, 0) + y.get(k, 0) for k in set(x) | set(y) }
原文由 Light Yagmi 发布,翻译遵循 CC BY-SA 4.0 许可协议
最简洁的方法是使用 Python 提供的工具。
就是这样。
map(str.split, f)
正在制作一个生成器,该生成器返回list
每行的单词。包装在chain.from_iterable
将其转换为一次生成一个单词的单个生成器。Counter
接受一个可迭代的输入并计算其中的所有唯一值。最后,你return
一个dict
类对象(一个Counter
),在创建过程中,你只存储一个一次一行数据和总计数,而不是一次整个文件。理论上,在 Python 2.7 和 3.1 上,您自己循环链式结果并使用
dict
或collections.defaultdict(int)
来计数(因为Counter
在 Python 中实现,这在某些情况下可能会使其变慢),但让Counter
完成工作更简单且更自我记录(我的意思是,整个目标是计数,所以使用Counter
)。除此之外,在 CPython(参考解释器)3.2 及更高版本Counter
上有一个 C 级加速器,用于计算可迭代输入,它的运行速度比你用纯 Python 编写的任何东西都要快。更新: 您似乎想要去除标点符号和不区分大小写,所以这是我之前代码的一个变体:
Your code runs much more slowly because it’s creating and destroying many small
Counter
andset
objects, rather than.update
-ing a singleCounter
每行一次(虽然比我在更新的代码块中给出的稍慢,但至少在比例因子上算法相似)。