Python MemoryError: не удается выделить память массива
у меня есть файл CSV 250 MB, который мне нужно прочитать с ~7000 строк и ~9000 столбцов. Каждая строка представляет изображение, а каждый столбец-пиксель (значение в оттенках серого 0-255)
я начал с простого np.loadtxt("data/training_nohead.csv",delimiter=",")
но это дало мне ошибку памяти. Я подумал, что это странно, так как я запускаю 64-битный Python с 8 гигабайтами памяти, и он умер после использования только около 512 МБ.
С тех пор я пробовал несколько других тактик, в том числе:
-
import fileinput
и читайте по одной строке за раз, добавляя их в массив -
np.fromstring
после прочтения во всем файле np.genfromtext
- ручной разбор файла (так как все данные целые, это было довольно легко кодировать)
каждый метод дал мне тот же результат. MemoryError около 512 МБ. Задаваясь вопросом, есть ли что-то особенное в 512MB, я создал простую тестовую программу, которая заполнила память до python разбился:
str = " " * 511000000 # Start at 511 MB
while 1:
str = str + " " * 1000 # Add 1 KB at a time
это не произошло до 1 концерта. Я также, просто для удовольствия, попробовал:str = " " * 2048000000
(заполните 2 концерта) - это прошло без сучка и задоринки. Заполнил ОЗУ и никогда не жаловался. Таким образом, проблема заключается не в общем объеме ОЗУ, который я могу выделить, а в том, сколько раз я могу выделить память...
Я google вокруг бесплодно, пока не нашел этот пост:Python из памяти в большом CSV-файле (numpy)
Я скопировал код из ответьте точно:
def iter_loadtxt(filename, delimiter=',', skiprows=0, dtype=float):
def iter_func():
with open(filename, 'r') as infile:
for _ in range(skiprows):
next(infile)
for line in infile:
line = line.rstrip().split(delimiter)
for item in line:
yield dtype(item)
iter_loadtxt.rowlength = len(line)
data = np.fromiter(iter_func(), dtype=dtype)
data = data.reshape((-1, iter_loadtxt.rowlength))
return data
вызов iter_loadtxt("data/training_nohead.csv")
дал немного другую ошибку на этот раз:
MemoryError: cannot allocate array memory
Googling эта ошибка я нашел только один, не очень полезный, сообщение:Ошибка памяти (MemoryError) при создании логического массива NumPy (Python)
поскольку я запускаю Python 2.7, это не было моей проблемой. Любая помощь будет оценена.
1 ответов
С некоторой помощью @J. F. Sebastian я разработал следующий ответ:
train = np.empty([7049,9246])
row = 0
for line in open("data/training_nohead.csv")
train[row] = np.fromstring(line, sep=",")
row += 1
конечно, этот ответ предполагал предварительное знание количества строк и столбцов. Если у вас нет этой информации перед рукой, количество строк всегда займет некоторое время, чтобы вычислить, как вы должны прочитать весь файл и подсчитать \n
символы. Что-то вроде этого будет достаточно:
num_rows = 0
for line in open("data/training_nohead.csv")
num_rows += 1
количество столбцов, если каждая строка имеет одинаковое количество столбцов вы можете просто посчитать первую строку, в противном случае вам нужно отслеживать максимум.
num_rows = 0
max_cols = 0
for line in open("data/training_nohead.csv")
num_rows += 1
tmp = line.split(",")
if len(tmp) > max_cols:
max_cols = len(tmp)
это решение лучше всего работает для числовых данных, так как строка, содержащая запятую, может действительно усложнить ситуацию.