Существует ли память эффективный и быстрый способ загрузить большие json файлы в Python?

У меня есть некоторые json файлы с 500 МБ. Если я буду использовать "тривиальный" json.load для загрузки его содержания внезапно, то он использует большую память.

Существует ли способ считать частично файл? Если бы это был текст, строка разграничила файл, я смог бы выполнить итерации по строкам. Я ищу аналогию с ним.

Какие-либо предложения?Спасибо

56
задан Jon Seigel 14 March 2010 в 20:15
поделиться

6 ответов

Краткий ответ: нет.

Чтобы правильно разделить файл json, нужно хорошо знать граф объектов json.

Однако, если у вас есть эти знания, вы можете реализовать файловый объект, который обертывает файл json и выделяет нужные фрагменты.

Например, если вы знаете, что ваш файл json представляет собой единственный массив объектов, вы можете создать генератор, который обертывает файл json и возвращает фрагменты массива.

Чтобы правильно разбить json-файл, вам нужно будет выполнить синтаксический анализ содержимого строки.

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

-1
ответ дан 26 November 2019 в 17:21
поделиться

По поводу вашего упоминания о нехватке памяти я должен спросить, действительно ли вы управляете памятью. Используете ли вы ключевое слово "del" для удаления старого объекта перед попыткой чтения нового? Python никогда не должен молча сохранять что-то в памяти, если вы его удалили.

3
ответ дан 26 November 2019 в 17:21
поделиться

в дополнение к @codeape

Я бы попытался написать собственный парсер json, который поможет вам понять структуру большого двоичного объекта JSON, с которым вы имеете дело. Распечатайте только названия ключей и т. Д. Создайте иерархическое дерево и решите (сами), как вы можете его разбить. Таким образом, вы можете делать то, что предлагает @codeape - разбивать файл на более мелкие части и т. Д.

1
ответ дан 26 November 2019 в 17:21
поделиться

Другая идея - попробовать загрузить его в базу данных хранилища документов, такую ​​как MongoDB. Он хорошо справляется с большими двоичными объектами JSON. Хотя вы можете столкнуться с той же проблемой при загрузке JSON - избегайте проблемы, загружая файлы по одному.

Если путь вам подходит, то вы можете взаимодействовать с данными JSON через их клиента и, возможно, вам не придется хранить весь большой двоичный объект в памяти

http://www.mongodb.org/

2
ответ дан 26 November 2019 в 17:21
поделиться

Таким образом, проблема не в том, что каждый файл слишком большой, а в том, что их слишком много, и они, кажется, складываются в памяти. Сборщик мусора Python должен быть в порядке, если вы не храните ссылки, которые вам не нужны. Трудно точно сказать, что происходит без какой-либо дополнительной информации, но некоторые вещи вы можете попробовать:

  1. Модульный код. Сделайте что-то вроде:

     для json_file в list_of_files:
     process_file(json_file)
    

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

  2. Обрабатывайте каждый файл в отдельном процессе. Вместо синтаксического анализа всех JSON-файлов сразу, напишите программа, которая анализирует только один и передает каждый из них из сценария оболочки или из другого python процесс, вызывающий скрипт через подпроцесс .. Попен. Это немного менее элегантно, но если больше ничего не работает,Это гарантирует, что вы не будете удерживать устаревшие данные из одного файла в следующий.

Надеюсь, это поможет.

14
ответ дан 26 November 2019 в 17:21
поделиться

«сборщик мусора должен освободить память»

Верно.

Поскольку это не так, значит, что-то еще не так. Как правило, проблема с бесконечным ростом памяти - это глобальные переменные.

Удалить все глобальные переменные.

Превратите весь код уровня модуля в более мелкие функции.

3
ответ дан 26 November 2019 в 17:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: