2013-08-18 62 views
1

有文本文件(约300米),并需要计数前N个频率的单词。第一步是从磁盘读取它,现在我只需使用open.read().lower()(不区分大小写)是否有更有效的方法来处理IO部分?测试机有8核4G内存和Linux系统,python版本为2.6。什么是更有效的方式来读取文本文件

+0

你需要多快?你可以得到一个基线,这个基线能够很好地将IO和词分解为时间wc -w m30text.txt→0.67s wallclock。 Martijn对同样30M字(磁盘上34MB)文本文件的回答是:3.0s。无论您拥有多少核心,Python GIL都可能使您无法减少2.3s来填充Counter对象。 – msw

+0

感谢python对于这类问题并不是一种合适的语言 – nzomkxia

+0

这并不是所有的预期结论。对于文件可以被读取和分析成文字的速度有一个较低的限制。如果你已经测量了一个正确的替代实现,没有缺陷,并且性能更好,那么向我们展示。在你测量它之前,它不存在,大多数人对Python内在函数性能的直觉通常是不正确的。 – msw

回答

4

是的,过程行文件行的迭代器:

with open(filename) as inputfile: 
    for line in inputfile: 
     line = line.lower() 

这将缓冲器的读取性能,但不把尽可能多的压力,你的记忆,避免了必须换。

接下来,使用collections.Counter()为您做频率计数。它将以纯Python代码中最有效的方式处理计数并为您选择前N个单词。

一个天真的方式来获取单词将是拆分空白的行;结合与发电机表达式可以给你在一行代码中的所有字数:

from collections import Counter 

with open(filename) as inputfile: 
    counts = Counter(word for line in inputfile for word in line.lower().split()) 

for word, frequency in counts.most_common(N): 
    print '{<40} {}'.format(word, frequency) 

在Python 2.7版添加的Counter类;对于2.6你可以使用this backport

+0

谢谢,正在逐行读取只有当内存无法加载所有数据时才有意义?计数器()使用多线程模块来执行频率字计数作业吗? – nzomkxia

+0

不,Counter()不使用任何多进程或线程技巧。你必须自己做,然后重新组合结果。 Counter()对象可以很容易地求和。 –

+0

Counter()比以前使用的堆更快,我会尝试多进程,谢谢 – nzomkxia

相关问题