2013-08-18 113 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

相關問題