在Python中计算1GB文本文件的词频
我正在尝试计算一个大小为1.2 GB的文本文件中的单词频率,这个文件大约有2.03亿个单词。我使用了以下的Python代码。但它给我报了内存错误。有没有什么解决办法?
这是我的代码:
import re
# this one in honor of 4th July, or pick text file you have!!!!!!!
filename = 'inputfile.txt'
# create list of lower case words, \s+ --> match any whitespace(s)
# you can replace file(filename).read() with given string
word_list = re.split('\s+', file(filename).read().lower())
print 'Words in text:', len(word_list)
# create dictionary of word:frequency pairs
freq_dic = {}
# punctuation marks to be removed
punctuation = re.compile(r'[.?!,":;]')
for word in word_list:
# remove punctuation marks
word = punctuation.sub("", word)
# form dictionary
try:
freq_dic[word] += 1
except:
freq_dic[word] = 1
print 'Unique words:', len(freq_dic)
# create list of (key, val) tuple pairs
freq_list = freq_dic.items()
# sort by key or word
freq_list.sort()
# display result
for word, freq in freq_list:
print word, freq
这是我收到的错误信息:
Traceback (most recent call last):
File "count.py", line 6, in <module>
word_list = re.split('\s+', file(filename).read().lower())
File "/usr/lib/python2.7/re.py", line 167, in split
return _compile(pattern, flags).split(string, maxsplit)
MemoryError
2 个回答
5
问题在于你试图把整个文件一次性读入内存。解决办法是逐行读取文件,计算每一行的单词数,然后把这些结果加起来。
16
问题就出在这里:
file(filename).read()
这段代码是把整个文件的内容都读进一个字符串里。其实,如果你逐行或者分块处理文件,就不会遇到内存问题了。
with open(filename) as f:
for line in f:
你还可以使用一个叫做 collections.Counter 的工具来统计单词出现的频率,这样会更方便。
In [1]: import collections
In [2]: freq = collections.Counter()
In [3]: line = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod'
In [4]: freq.update(line.split())
In [5]: freq
Out[5]: Counter({'ipsum': 1, 'amet,': 1, 'do': 1, 'sit': 1, 'eiusmod': 1, 'consectetur': 1, 'sed': 1, 'elit,': 1, 'dolor': 1, 'Lorem': 1, 'adipisicing': 1})
如果你想统计更多的单词,
In [6]: freq.update(line.split())
In [7]: freq
Out[7]: Counter({'ipsum': 2, 'amet,': 2, 'do': 2, 'sit': 2, 'eiusmod': 2, 'consectetur': 2, 'sed': 2, 'elit,': 2, 'dolor': 2, 'Lorem': 2, 'adipisicing': 2})
collections.Counter
是 dict
的一个子类,所以你可以用你已经熟悉的方式来使用它。此外,它还有一些很有用的方法来计数,比如 most_common。