Python: ошибка подсчета строк - PullRequest
       1

Python: ошибка подсчета строк

2 голосов
/ 19 сентября 2011

Основываясь на предложениях, которые я получил на этом форуме, я использую следующий код (пример) для подсчета строк.

phrase_words = ['red car', 'no lake', 'newjersey turnpike']
lines = ['i have a red car which i drove on newjersey', 'turnpike. when i took exit 39 there was no', 'lake. i drove my car on muddy roads which turned my red', 'car into brown. driving on newjersey turnpike can be confusing.']
text = " ".join(lines)
dict = {phrase: text.count(phrase) for phrase in phrase_words}

Требуемый вывод и вывод примера кода:

{'newjersey turnpike': 2, 'red car': 2, 'no lake': 1}

Этот код прекрасно работал с текстовым файлом размером менее 300 МБ.Я использовал текстовый файл размером 500 МБ + и получил следующую ошибку памяти:

    y=' '.join(lines)
MemoryError

Как мне преодолеть это?Спасибо за вашу помощь!

Ответы [ 2 ]

5 голосов
/ 19 сентября 2011

Этот алгоритм требует только две строки в памяти одновременно.Предполагается, что ни одна фраза не будет занимать три строки:

from itertools import tee, izip
from collections import defaultdict

def pairwise(iterable): # recipe from itertools docs
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)
d = defaultdict(int)
phrase_words = ['red car', 'no lake', 'newjersey turnpike']
lines = ['i have a red car which i drove on newjersey',
         'turnpike. when i took exit 39 there was no',
         'lake. i drove my car on muddy roads which turned my red',
         'car into brown. driving on newjersey turnpike can be confusing.']

for line1, line2 in pairwise(lines):
    both_lines= ' '.join((line1, line2))
    for phrase in phrase_words:
        # counts phrases in first line and those that span to the next
        d[phrase] += both_lines.count(phrase) - line2.count(phrase)
for phrase in phrase_words:
    d[phrase] += line2.count(phrase) # otherwise last line is not searched
3 голосов
/ 19 сентября 2011

Вам не нужно пытаться делать все сразу. Вместо того, чтобы загружать огромный файл в память, а затем анализировать его, вы должны загружать файл по несколько (сто) строк за раз и пытаться найти строки в этих строках.

Пока ваши фрагменты перекрывают как минимум макс (длина (фраза) для фразы в фразе-словах), вы не пропустите ни одного попадания.

Так что вы можете сделать что-то вроде:

text = ''
occurs = {}
overlap_size = max(len(phrase) for phrase in phrase_words)
for phrase in phrase_words:
    occurs[phrase] = 0

while lines:

    text += ' '.join(lines[:1000])
    lines = lines[100:]
    for phrase in phrase_words:
        # this makes sure we don't double count, and also gets all matches (probably)
        occurs[phrase] += text[overlap_size - len(phrase):].count(phrase)
    text = text[-1 * overlap_size:]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...