2013-02-03 2 views
4

크기가 1.2GB 인 텍스트 파일의 단어 빈도를 계산하려고하는데 약 2 억 3 천만 단어였습니다. 다음 Python 코드를 사용하고 있습니다. 그러나 그것은 나에게 메모리 오류를 준다. 이것에 대한 해결책이 있습니까?Word 파이썬에서 1Gb 텍스트 파일의 빈도 계산

여기 내 코드입니다 :

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 

답변

13

이 문제는 바로 여기 시작 :

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.Counterdict의 서브 클래스입니다, 그래서 당신은 당신이 이미 잘 알고있는 방법으로 사용할 수 있습니다. 또한, 그것은 유용한 카운트 방법을 가지고 있습니다 (예 : most_common).

5

문제는 당신이 메모리에 전체 파일을 읽으려고하는 것입니다. 해결 방법은 파일을 한 줄씩 읽은 다음 각 줄의 단어 수를 계산하고 결과를 합산합니다.