Чтение в большом сжатом файле json с помощью pyarrow, аналогичной функциональности pandas reader

#pyarrow #apache-arrow

#pyarrow #apache-arrow

Вопрос:

У меня есть большой сжатый файл json, который в несжатом виде составляет около ~ 128 ГБ в виде одного файла. При сжатии .gz файл составляет около ~ 21 ГБ. Я хотел бы использовать pyarrow для чтения файла по частям и преобразования в набор данных parquet. Я хотел имитировать функциональность panda reader, но столкнулся с некоторыми проблемами.

У меня работает следующий код, в котором сжатый файл json считывается через pandas read_json на фрагменты, затем эти фрагменты преобразуются в таблицы apache arrow, а затем записываются в наборы данных parquet:

 reader = pd.read_json("file.json.gz", lines=True, chunksize=5000000) 
for chunk in reader:
   arrow_table = pa.Table.from_pandas(chunk,nthreads=4)
   pq.write_to_dataset(arrow_table,root_path="dir")
  

Этот код дает мне ожидаемые результаты, однако я хотел бы использовать apache arrow напрямую, без необходимости сначала извлекать фрагментированные фреймы данных pandas, а затем выводить их в таблицу apache arrow. В первую очередь я хотел бы добиться некоторого увеличения производительности, учитывая возможность многопоточного чтения с помощью apache arrow по сравнению с pandas read_json.

Я попытался использовать опции чтения класса pyarrow.json (https://arrow.apache.org/docs/python/generated/pyarrow.json .ReadOptions.html#pyarrow.json.Варианты чтения) однако, когда я запускаю следующий код, мне кажется, что apache arrow сначала распаковывает весь файл в памяти, прежде чем читать его в соответствии с размером блока, который я установил в параметре block_size, учитывая размер файла, который я получаю из ошибок памяти, если я позволяю коду выполняться.

 from pyarrow import json 
opts = json.ReadOptions(block_size=4096) 
with json.read_json('file.json.gz',opts) as f: 
    table = f 
    pq.write_to_dataset(table, root_path='dir')
  

Вместо with json.read_json я изучал функциональность входного потока, аналогичную функции чтения файловых потоков, но не уверен, что это правильный маршрут.

Любые рекомендации приветствуются.

Ответ №1:

Это звучит похоже на https://issues.apache.org/jira/browse/ARROW-10372 . Начиная с версии 2.0.0, функция dataset не поддерживает чтение сжатых CSV или файлов JSON. Не могли бы вы прокомментировать свой вариант использования по этому вопросу?

Комментарии:

1. Эй, Нил, я добавлю к проблеме, спасибо за ответ! Мне интересно, хотя, если нет способа сделать это в pyarrow вообще, независимо от того, использует ли он более новую функциональность набора данных или нет? Я бы подумал, что мог бы аналогичным образом разделить файл на таблицы со стрелками вместо фреймов данных, но, возможно, это не так.

2. Программа чтения CSV в arrow имеет опцию «потоковая передача» (см. arrow.apache.org/docs/python/csv.html#incremental-reading ), однако я не вижу ничего подобного тому, что в настоящее время реализовано для JSON.

3. @joris спасибо за это, как вы упомянули, в настоящее время не для JSON, а также всегда однопоточный, поэтому я не уверен, что я бы увидел большой прирост производительности от pandas, но возможно. Теперь я добился некоторого прогресса, получая исключение превышения максимального количества строк при чтении.