我想计算文本文件中所有单词的频率。
>>> countInFile('test.txt')
如果目标文本文件是这样的,应该返回 {'aaa':1, 'bbb': 2, 'ccc':1}
:
# test.txt
aaa bbb ccc
bbb
我在 some posts 之后用纯 python 实现了它.但是,我发现纯 python 方式由于文件大小(> 1GB)而不足。
我认为借用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) }
最佳答案
最简洁的方法是使用 Python 提供的工具。
from future_builtins import map # Only on Python 2
from collections import Counter
from itertools import chain
def countInFile(filename):
with open(filename) as f:
return Counter(chain.from_iterable(map(str.split, f)))
就是这样。 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 编写的任何东西都快。
更新:您似乎希望去除标点符号和不区分大小写,所以这是我早期代码的一个变体:
from string import punctuation
def countInFile(filename):
with open(filename) as f:
linewords = (line.translate(None, punctuation).lower().split() for line in f)
return Counter(chain.from_iterable(linewords))
您的代码运行速度要慢得多,因为它创建和销毁许多小的 Counter
和 set
对象,而不是 .update
-ing 单个Counter
每行一次(虽然比我在更新的代码块中给出的稍慢,但在缩放因子上至少在算法上相似)。
关于python - 有效计算python中的词频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35857519/