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

Как читать большой json?

Я получаю json файлы с данными для анализа в R, для которых я использую RJSONIO-пакет:

library(RJSONIO)
filename <- "Indata.json"
jFile <- fromJSON(filename)

Когда json файлы больше 300 МБ (несжатые), мой компьютер начинает использовать память подкачки и продолжает синтаксический анализ (fromJSON) в течение нескольких часов. 200MB файл занимает всего около минуты для разбора.

Я использую R 2.14 (64 бит) на 64-битной Ubuntu с 16 ГБ оперативной памяти, поэтому я удивлен, что замена требуется уже около 300 МБ json.

Что я могу сделать, чтобы читать большие jsons? Есть ли что-то в настройках памяти, которые все испортили? Я перезапустил R и запустил только три строки выше. Json файл содержит 2-3 столбца с короткими строками и 10-20 столбцов с номерами от 0 до 1000000. I.e. это число строк, которое делает большой размер (более миллиона строк в анализируемых данных).


Обновление: Из комментариев я узнал, что rjson сделан больше на C, поэтому я попробовал. 300 МБ файл, который с RJSONIO (согласно Ubuntu System Monitor) достиг 100% -ной памяти (с 6% базовой линии) и продолжал замену, нуждался только в 60% -ной памяти с пакетом rjson, и разбор проводился в разумные сроки (минуты).

4b9b3361

Ответ 1

Хотя ваш вопрос не определяет эту деталь, вы можете захотеть убедиться, что загрузка всего JSON в память на самом деле вам нужна. Похоже, RJSONIO - это API на основе DOM.

Какое вычисление вам нужно сделать? Можете ли вы использовать потоковой парсер? Примером SAX-подобного потокового анализатора для JSON является yajl.

Ответ 2

Даже если вопрос очень старый, это может быть полезно для кого-то с аналогичной проблемой.

Функция jsonlite::stream_in() позволяет определить pagesize, чтобы установить количество строк, считанных за раз, и настраиваемая функция, применяемая к этому подмножеству на каждой итерации, может быть предоставлена ​​как handler. Это позволяет работать с очень большими JSON файлами, не одновременно считывая все в память.

stream_in(con, pagesize = 5000, handler = function(x){
    # Do something with the data here
})

Ответ 3

Не для размера памяти, а для скорости, для довольно небольшого набора данных iris (всего 7088 байт) пакет RJSONIO на порядок медленнее, чем rjson. Не используйте метод "R", если вам действительно не нужно! Обратите внимание на разные единицы в двух наборах результатов.

library(rjson) # library(RJSONIO)
library(plyr)
library(microbenchmark)
x <- toJSON(iris)
(op <- microbenchmark(CJ=toJSON(iris), RJ=toJSON(iris, method='R'),
  JC=fromJSON(x), JR=fromJSON(x, method='R') ) )

# for rjson on this machine...
Unit: microseconds
  expr        min          lq     median          uq        max
1   CJ    491.470    496.5215    501.467    537.6295    561.437
2   JC    242.079    249.8860    259.562    274.5550    325.885
3   JR 167673.237 170963.4895 171784.270 172132.7540 190310.582
4   RJ    912.666    925.3390    957.250   1014.2075   1153.494

# for RJSONIO on the same machine...
Unit: milliseconds
  expr      min       lq   median       uq      max
1   CJ 7.338376 7.467097 7.563563 7.639456 8.591748
2   JC 1.186369 1.234235 1.247235 1.265922 2.165260
3   JR 1.196690 1.238406 1.259552 1.278455 2.325789
4   RJ 7.353977 7.481313 7.586960 7.947347 9.364393