Выборка Python с использованием readline дает ошибку памяти - PullRequest
0 голосов
/ 01 ноября 2018

Я попытался сэмплировать файл данных с более чем 260 миллионами строк, создав равномерно распределенную выборку с фиксированным размером 1000 выборок.

Я сделал следующее:

import random

file = "input.txt"
output = open("output.txt", "w+", encoding = "utf-8")

samples = random.sample(range(1, 264000000), 1000)
samples.sort(reverse=False)

with open(file, encoding = "utf-8") as fp:
    line = fp.readline()
    count = 0
    while line:
        if count in samples:
            output.write(line)
            samples.remove(count)
        count += 1
        line = fp.readline()

Этот код привел к ошибке памяти без дальнейшего описания. Почему этот код может выдавать ошибку памяти?

Насколько я знаю, он должен читать мой файл построчно. Размер файла составляет 28,4 ГБ, поэтому он не может быть прочитан целиком, поэтому я прибег к подходу readline (). Как я могу это исправить, чтобы можно было обработать весь файл независимо от его размера? \

EDIT: Последние попытки выдают эту ошибку, которая практически идентична каждому из предыдущих сообщений об ошибках, которые я получил до сих пор

MemoryError                               Traceback (most recent call last)
<ipython-input-1-a772dad1ea5a> in <module>()
     12 with open(file, encoding = "utf-8") as fp:
     13     count = 0
---> 14     for line in fp:
     15         if count in samples:
     16             output.write(line)

~\Anaconda3\lib\codecs.py in decode(self, input, final)
    320         # decode input (taking the buffer into account)
    321         data = self.buffer + input
--> 322         (result, consumed) = self._buffer_decode(data, self.errors, final)
    323         # keep undecoded input until the next call
    324         self.buffer = data[consumed:]

MemoryError: 

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

решаемые

Я наконец-то решил проблему: весь код здесь работает правильно, проблема диапазона действительно присутствует только в версиях до 3.0, где это должно быть xrange (1, 264000000).

Входной файл был создан в другом файле кода, где было написано следующее:

with open(file, encoding = "utf-8", errors = 'ignore') as fp:  
line = fp.readline()
    while line:
        input_line = line.split(sep="\t")
        output.write(input_line[1] + "," + input_line[2])
        line = fp.readline()

Проблема здесь в том, что этот код не создает файл со строками, а просто добавляет информацию в первую строку. Поэтому весь файл читался как одна большая строка, а не как файл с большим количеством строк для повторения.

Большое спасибо за вашу помощь и мои искренние извинения за то, что проблема была в другом месте в моем проекте.

0 голосов
/ 01 ноября 2018

Похоже, эта строка вызывает огромный всплеск памяти:

samples = random.sample(range(1, 264000000), 1000)

Я предполагаю, что этот вызов заставляет python создать все 264M int в этом диапазоне, прежде чем он сможет выполнить выборку. Попробуйте использовать этот код для выборки в том же диапазоне без замены:

from random import randint

file = "input.txt"
output = open("output.txt", "w+", encoding = "utf-8")

samples = set()
while len(samples) < 1000:
    random_num = randint(0, 264000000)
    if random_num not in samples:
        samples.add(random_num)

with open(file, encoding = "utf-8") as fp:
    count = 0
    for line in fp:
        if count in samples:
            output.write(line)
            samples.remove(count)
        count += 1

        if not samples: break
...