我想计算文本文件中所有单词的频率。
>>> countInFile('test.txt')
如果目标文本文件如下所示,则应返回{'aaa':1, 'bbb': 2, 'ccc':1}
:
# test.txt
aaa bbb ccc
bbb
我已经用纯python在some posts之后实现了它。但是,我发现纯粹的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提供的工具。
就这样。
map(str.split, f)
正在生成一个生成器,从每行返回list
s个单词。包装chain.from_iterable
将其转换为一次生成一个单词的单个生成器。Counter
接受一个input iterable并计算其中的所有唯一值。最后,像return
adict
一样的对象(aCounter
)存储所有唯一的单词及其计数,在创建过程中,一次只存储一行数据和总计数,而不是一次存储整个文件。理论上,在Python2.7和3.1上,您可以自己对链接的结果进行循环,并使用
dict
或collections.defaultdict(int)
进行计数(因为Counter
是在Python中实现的,在某些情况下可能会使其变慢),但是让Counter
完成这项工作更简单,也更具自文档性(我的意思是,整个目标是计数,所以使用一个Counter
)。除此之外,在C Python(引用解释器)3.2和更高版本上,Counter
有一个C级加速器,用于计算iterable输入,它的运行速度比纯Python编写的任何东西都要快。更新:您似乎希望去掉标点符号,并且不区分大小写,下面是我以前代码的一个变体:
您的代码运行得慢得多,因为它正在创建和销毁许多小的
Counter
和set
对象,而不是.update
-每行一次Counter
(虽然比我在更新的代码块中给出的速度稍慢,但至少在算法上与缩放因子相似)。这就足够了。
一种高效准确的记忆方法是利用
scikit
中的计数器矢量器(用于ngram提取)word_tokenize
的NLTKnumpy
收集计数的矩阵和collections.Counter
用于收集计数和词汇例如:
[出局]:
实际上,您也可以这样做:
让我们
timeit
:[出局]:
注意^{} 也可以使用一个文件而不是一个字符串,这里不需要将整个文件读入内存。代码中:
相关问题 更多 >
编程相关推荐