Write_parquet пакета Give не поддерживает добавление, есть ли альтернатива?

Мне нужно создать файл паркета, записывая части данных за раз, учитывая ограничения памяти. Пакет arrowwrite_parquet не поддерживает эту функциональность. Я понимаю, что могу писать в несколько файлов паркета и перечитывать их как «набор данных». Интересно, существуют ли альтернативные пакеты/решения для создания одного файла паркета. Последующие пользователи требуют этого. Python поддерживает добавление, но оно существенно портит поля даты и столбцы с плавающей запятой и не является вариантом.

Re: «Python поддерживает добавление», существует ли проблема с поведением, которое вы видите в трекере проблем Arrow (github.com/apache/arrow/issues)? Если действительно есть проблема, возможно, было бы хорошо ее исправить.

amoeba 21.06.2024 02:07

Вот похожий вопрос на форуме Posit: forum.posit.co/t/appending-to-parquet-file-with-arrow/68383/‌​3

Jon Spring 21.06.2024 02:27

У меня нет искрового кластера, а на моей единственной машине память является ограничением.

Gopala 21.06.2024 03:52

Действительно ли вам нужно добавить что-то к существующему файлу паркета или вам просто нужно создать новый файл паркета, написать немного, затем написать еще немного и т. д. и, наконец, закрыть все это в одном сеансе?

G. Grothendieck 21.06.2024 06:18

У меня недостаточно памяти для хранения всех данных. Буду читать по частям и записывать. Итак, добавление необходимо. Я знаю, что есть способ записывать фрагменты, но это мне не поможет, поскольку для начала все равно необходимо хранить все данные в памяти.

Gopala 22.06.2024 04:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
102
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Запись файла паркета частями не требует, чтобы все данные находились в оперативной памяти одновременно.

Чтобы продемонстрировать это первое определение gen_data(i, size), которое создает фрейм данных с size строками последовательно, начиная с i, чтобы имитировать процесс, обсуждаемый в вопросе.

Теперь с помощью пакетаpeakRAM мы проверяем, сколько оперативной памяти требуется для создания кадра данных со строками 1e7 (76,3/макс. 152,6 МБ). Затем генерируйте одну десятую часть данных за раз и записывайте их в паркет в виде фрагмента, и в этом случае мы используем только 0,0/макс. 26,7 МБ. Это показывает, что нам не нужно было сразу хранить весь фрейм данных в оперативной памяти.

Ниже мы изменили источник write_parquet в пакете стрелок, чтобы записывать данные частями.

library(arrow)
library(peakRAM)

invisible(gc())

gen_data <- function(i, size) {
  data.frame(x = as.numeric(seq(i, length = size)))
}

f <- function() {
  # define inputs
  path <- "test.parquet"

  # open
  schema <- arrow_table(gen_data(1, 1))$schema # gen 1 row to get schema
  sink <- FileOutputStream$create(path) 
  writer <- ParquetFileWriter$create(schema = schema, sink = sink,
    properties = ParquetWriterProperties$create(names(schema)))

  # writes
  for(i in seq(1, 1e7, 1e6)) { 
    dat <- gen_data(i, 1e6)
    writer$WriteTable(arrow_table(dat), chunk_size = 1e6)
    gc()
  }

  # close
  writer$Close()
  sink$close()

}

Теперь проверьте это:

if (file.exists("test.parquet")) unlink("test.parquet")
invisible(gc())
peakRAM(gen_data(1, 1e7), f())
##       Function_Call Elapsed_Time_sec Total_RAM_Used_MiB Peak_RAM_Used_MiB
## 1 gen_data(1,1e+07)             0.37               76.3             152.6
## 2               f()             1.78                0.0              26.7

Другие вопросы по теме