2016-05-13 2 views
4

Я пытаюсь проанализировать большой (~ 100 МБ) json-файл с помощью пакета ijson, который позволяет мне эффективно взаимодействовать с файлом. Однако, после написания какого-то кода, как это,Использование python ijson для чтения большого json-файла с несколькими объектами json

with open(filename, 'r') as f: 
    parser = ijson.parse(f) 
    for prefix, event, value in parser: 
     if prefix == "name": 
      print(value) 

Я обнаружил, что код разбирает только первую строку, а не остальные строки из файла !!

Вот как часть моего файла JSON выглядит следующим образом:

{"name":"accelerator_pedal_position","value":0,"timestamp":1364323939.012000} 
{"name":"engine_speed","value":772,"timestamp":1364323939.027000} 
{"name":"vehicle_speed","value":0,"timestamp":1364323939.029000} 
{"name":"accelerator_pedal_position","value":0,"timestamp":1364323939.035000} 

На мой взгляд, я думаю ijson разбирает только один объект JSON.

Может кто-нибудь предложить вам, как обойти это?

+0

Возможный дубликат http://stackoverflow.com/questions/10715628/opening-a-large-json-file-in-python – ErikR

+0

Ну, предоставленный вами фрагмент выглядит как _set_ из JSON. То есть вы должны читать строки один за другим и отдельно анализировать его. – user3159253

+0

Кстати, поскольку каждая строка коротка, вам не нужен ijson, вы можете использовать 'json.loads()'. – user3159253

ответ

3

Поскольку при условии кусок выглядит как набор строк, каждая из составляющих независимую JSON, он должен быть обработан соответствующим образом:

# each JSON is small, there's no need in iterative processing 
import json 
with open(filename, 'r') as f: 
    for line in f: 
     data = json.loads(line) 
     # data[u'name'], data[u'engine_speed'], data[u'timestamp'] now 
     # contain correspoding values 
+0

Спасибо за ответ, я спрашиваю, не загрузит ли этот файл отверстия в оперативную память? , если он загружает только одну строку во времени, так что это потрясающе –

+0

конечно 'для строки в f:' читает одну строку за раз. Проверьте http://stackoverflow.com/questions/17246260/python-readlines-usage-and-efficient-practice-for-reading – user3159253

+0

спасибо человеку, поэтому я поеду за json.loads(), у меня хороший день –

1

К сожалению ijson библиотека (v2.3 по состоянию на март 2018 года) не обрабатывает разбор нескольких объектов JSON. Он может обрабатывать только 1 общий объект, и если вы попытаетесь проанализировать второй объект, вы получите сообщение об ошибке: "ijson.common.JSONError: Additional data". Смотрите отчеты об ошибках здесь:

Это большое ограничение. Тем не менее, до тех пор, пока у вас есть разрывы строк (символ новой строки) после каждого объекта JSON, вы можете разобрать каждую одну строку за строкой независимо, как это:

import io 
import ijson 

with open(filename, encoding="UTF-8") as json_file: 
    cursor = 0 
    for line_number, line in enumerate(json_file): 
     print ("Processing line", line_number + 1,"at cursor index:", cursor) 
     line_as_file = io.StringIO(line) 
     # Use a new parser for each line 
     json_parser = ijson.parse(line_as_file) 
     for prefix, type, value in json_parser: 
      print ("prefix=",prefix, "type=",type, "value=",value) 
     cursor += len(line) 

Вы все еще потоковый файл, и не загружать его полностью в память, поэтому он может работать с большими файлами JSON. Он также использует технологию потоковой линии от: How to jump to a particular line in a huge text file? и использует enumerate() от: Accessing the index in Python 'for' loops

Смежные вопросы