Подтвердить что ты не робот

Ошибка памяти при использовании pandas read_csv

Я пытаюсь сделать что-то довольно простое, читая большой файл csv в фреймворк pandas.

data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)

Код либо терпит неудачу с MemoryError, либо просто не заканчивается.

Использование Mem в диспетчере задач остановилось на 506 Мбайт, и после 5 минут без изменений и активности процессора в этом процессе я его остановил.

Я использую pandas версию 0.11.0.

Мне известно, что с файловым парсером была проблема с памятью, но в соответствии с http://wesmckinney.com/blog/?p=543 это должно было быть исправлена.

Файл, который я пытаюсь прочитать, составляет 366 Мб, код выше работает, если я вырезал файл до чего-то короткого (25 Мб).

Также случилось, что я получаю всплывающее сообщение о том, что он не может написать адрес 0x1e0baf93...

StackTrace:

Traceback (most recent call last):
  File "F:\QA ALM\Python\new WIM data\new WIM data\new_WIM_data.py", line 25, in
 <module>
    wimdata = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2
)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 401, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 216, in _read
    return parser.read()
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 643, in read
    df = DataFrame(col_dict, columns=columns, index=index)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 394, in __init__
    mgr = self._init_dict(data, index, columns, dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 525, in _init_dict
    dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 5338, in _arrays_to_mgr
    return create_block_manager_from_arrays(arrays, arr_names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1820, in create_block_manager_from_arrays
    blocks = form_blocks(arrays, names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1872, in form_blocks
    float_blocks = _multi_blockify(float_items, items)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1930, in _multi_blockify
    block_items, values = _stack_arrays(list(tup_block), ref_items, dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1962, in _stack_arrays
    stacked = np.empty(shape, dtype=dtype)
MemoryError
Press any key to continue . . .

Немного фона - я пытаюсь убедить людей в том, что Python может делать то же самое, что и R. Для этого я пытаюсь реплицировать R script, который делает

data <- read.table(paste(INPUTDIR,config[i,]$TOEXTRACT,sep=""), HASHEADER, DELIMITER,skip=2,fill=TRUE)

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

4b9b3361

Ответ 1

Ограничение памяти Windows

Ошибки памяти происходят с python при использовании 32-битной версии в Windows. Это связано с тем, что 32-битные процессы по умолчанию получают только 2 ГБ памяти.

Трюки для снижения использования памяти

Если вы не используете 32-битный python в Windows, но хотите улучшить эффективность своей памяти при чтении файлов csv, есть трюк.

Функция pandas.read_csv имеет опцию dtype. Это позволяет pandas знать, какие типы существуют внутри ваших данных csv.

Как это работает

По умолчанию pandas будет пытаться угадать, что у dtypes ваш файл csv. Это очень тяжелая операция, потому что, пока она определяет dtype, она должна хранить все необработанные данные в виде объектов (строк) в памяти.

Пример

Скажем, ваш csv выглядит так:

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01

Этот пример, конечно, не представляет проблемы для чтения в память, но это всего лишь пример.

Если pandas должен был прочитать вышеуказанный файл csv без какой-либо опции dtype, возраст будет храниться в виде строк в памяти до тех пор, пока pandas не прочитает достаточно строк файла csv, чтобы сделать квалифицированное предположение.

Я думаю, что по умолчанию в pandas должно быть прочитано 1 000 000 строк, прежде чем угадать dtype.

Решение

Указывая dtype={'age':int} как опцию .read_csv(), пусть pandas знает, что возраст должен интерпретироваться как число. Это экономит много памяти.

Проблема с поврежденными данными

Однако, если ваш файл csv будет поврежден, например:

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01
Dennis, 40+, None-Ur-Bz

Затем указание dtype={'age':int} приведет к поломке команды .read_csv(), потому что она не может использовать "40+" для int. Поэтому тщательно очищайте свои данные!

Здесь вы можете увидеть, как использование памяти данных pandas намного выше, когда поплавки хранятся в виде строк:

Попробуйте сами

df = pd.DataFrame(pd.np.random.choice(['1.0', '0.6666667', '150000.1'],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 224544 (~224 MB)

df = pd.DataFrame(pd.np.random.choice([1.0, 0.6666667, 150000.1],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 79560 (~79 MB)

Ответ 2

У меня была та же проблема с памятью при простом чтении текстового файла с разделителями табуляции размером около 1 ГБ (более 5,5 миллионов записей), и это решило проблему с памятью:

df = pd.read_csv(myfile,sep='\t') # didn't work, memory error
df = pd.read_csv(myfile,sep='\t',low_memory=False) # worked fine and in less than 30 seconds

Spyder 3.2.3 Python 2.7.13 64bit

Ответ 3

Нет ошибки для Pandas 0.12.0 и NumPy 1.8.0.

Мне удалось создать большой DataFrame и сохранить его в файле csv, а затем успешно прочитать. Ниже приведен пример здесь. Размер файла составляет 554 Мб (он даже работал на 1,1 Гб файла, занимал больше времени, чтобы генерировать 1,1 Гб для использования в файлах 30 секунд). Хотя у меня есть 4 ГБ ОЗУ.

Мое предложение - попробовать обновить Pandas. Другое, что может быть полезно, - попробуйте запустить script из командной строки, потому что для R вы не используете Visual Studio (это уже было предложено в комментариях к вашему вопросу), следовательно, у него больше доступных ресурсов.

Ответ 4

Я столкнулся с этой проблемой, когда я работал на виртуальной машине, или где-то еще, где память ограничена. Он не имеет ничего общего с pandas или numpy или csv, но всегда будет иметь место, если вы попробуете использовать больше памяти, поскольку вы можете использовать ее, даже не в python.

Единственный шанс, который у вас есть, - это то, что вы уже пробовали, попытайтесь разделить большую вещь на более мелкие куски, которые вписываются в память.

Если вы когда-нибудь задавались вопросом о том, что такое MapReduce, вы узнали сами... MapReduce попытается распределить куски на многих машинах, вы попытаетесь обработать chunke на одной машине один за другим.

То, что вы обнаружили с конкатенацией файлов chunk, может быть проблемой, возможно, в этой операции есть какая-то копия... но, в конце концов, это может спасти вас в вашей текущей ситуации, но если ваш csv получит немного больше, вы можете снова бегать по этой стене...

Также может быть, что pandas настолько умный, что он фактически загружает отдельные блоки данных в память, если вы что-то делаете с ним, например, присоединяетесь к большому df?

Несколько вещей, которые вы можете попробовать:

  • Не загружайте сразу все данные, но разделяйте их на части
  • Насколько я знаю, hdf5 может делать эти куски автоматически и загружает только ту часть, в которой ваша программа работает в настоящее время
  • Посмотрите, поддерживаются ли типы, строка '0.111111' нуждается в большем количестве памяти, чем float
  • Что вам нужно на самом деле, если есть адрес в виде строки, вам может не понадобиться его для численного анализа...
  • База данных может помочь реализовать и загрузить только те части, которые вам действительно нужны (например, только 1% активных пользователей)

Ответ 5

Я использую Pandas в своем Linux-боксе и столкнулся со многими утечками памяти, которые были решены после обновления Pandas до последней версии после клонирования из github.

Ответ 6

Хотя это обходное решение не так сильно, как исправление, я бы попытался преобразовать этот CSV в JSON (должен быть тривиальным) и вместо этого использовать метод read_json - я писал и читал значимые JSON/dataframes (100s MB) в Pandas таким образом, без каких-либо проблем.