Я очень быстро читаю данные, используя новый arrow
пакет. Похоже, на довольно ранней стадии.
В частности, я использую паркетный столбчатый формат. Это преобразует обратно в a data.frame
в R, но вы можете получить еще более быстрое ускорение, если вы этого не сделаете. Этот формат удобен тем, что его можно использовать и в Python.
Мой основной сценарий использования этого - довольно ограниченный сервер RShiny. По этим причинам я предпочитаю хранить данные, прикрепленные к приложениям (то есть вне SQL), и поэтому требую небольшой размер файла и скорость.
Эта связанная статья обеспечивает сравнительный анализ и хороший обзор. Я привел некоторые интересные моменты ниже.
https://ursalabs.org/blog/2019-10-columnar-perf/
Размер файла
То есть файл Parquet вдвое меньше, чем даже сжатый CSV. Одна из причин, по которой файл Parquet такой маленький, заключается в кодировке словаря (также называемой «сжатие словаря»). Сжатие по словарю может дать значительно лучшее сжатие, чем использование байтового компрессора общего назначения, такого как LZ4 или ZSTD (которые используются в формате FST). Паркет был разработан для производства очень маленьких файлов, которые быстро читаются.
Скорость чтения
При управлении по типу выходных данных (например, сравнивая все выходные данные R data.frame друг с другом), мы видим, что производительность Parquet, Feather и FST находится в относительно небольшом поле друг от друга. То же самое относится и к выводам pandas.DataFrame. data.table :: fread впечатляюще конкурирует с размером файла 1,5 ГБ, но уступает другим по 2,5 ГБ CSV.
Независимый тест
Я выполнил некоторые независимые тесты для имитированного набора данных из 1 000 000 строк. По сути, я перетасовал кучу вещей, пытаясь бросить вызов сжатию. Также я добавил короткое текстовое поле случайных слов и два имитируемых фактора.
Данные
library(dplyr)
library(tibble)
library(OpenRepGrid)
n <- 1000000
set.seed(1234)
some_levels1 <- sapply(1:10, function(x) paste(LETTERS[sample(1:26, size = sample(3:8, 1), replace = TRUE)], collapse = ""))
some_levels2 <- sapply(1:65, function(x) paste(LETTERS[sample(1:26, size = sample(5:16, 1), replace = TRUE)], collapse = ""))
test_data <- mtcars %>%
rownames_to_column() %>%
sample_n(n, replace = TRUE) %>%
mutate_all(~ sample(., length(.))) %>%
mutate(factor1 = sample(some_levels1, n, replace = TRUE),
factor2 = sample(some_levels2, n, replace = TRUE),
text = randomSentences(n, sample(3:8, n, replace = TRUE))
)
Прочти и напиши
Написание данных легко.
library(arrow)
write_parquet(test_data , "test_data.parquet")
# you can also mess with the compression
write_parquet(test_data, "test_data2.parquet", compress = "gzip", compression_level = 9)
Чтение данных также легко.
read_parquet("test_data.parquet")
# this option will result in lightning fast reads, but in a different format.
read_parquet("test_data2.parquet", as_data_frame = FALSE)
Я проверил чтение этих данных по нескольким конкурирующим вариантам и получил немного другие результаты, чем в статье выше, что ожидается.
Этот файл далеко не такой большой, как эталонная статья, так что, возможно, в этом и заключается разница.
тесты
- выстр:rds test_data.rds (20,3 МБ)
- parquet2_native: (14,9 МБ с более высоким сжатием и
as_data_frame = FALSE
)
- parquet2: test_data2.parquet (14,9 МБ с более высоким сжатием)
- паркет: test_data.parquet (40,7 МБ)
- fst2: test_data2.fst (27,9 МБ с более высокой степенью сжатия)
- FST:fst test_data.fst (76,8 МБ)
- fread2: test_data.csv.gz (23,6 МБ)
- Fread: test_data.csv (98,7 МБ)
- feather_arrow: test_data.feather (157,2 МБ прочитано с
arrow
)
- feather: test_data.feather (157,2 МБ прочитано с
feather
)
наблюдения
Для этого конкретного файла, fread
на самом деле очень быстро. Мне нравится маленький размер файла из сильно сжатого parquet2
теста. Я могу потратить время на работу с собственным форматом данных, а неdata.frame
если мне действительно нужно ускорить работу.
Здесь fst
также отличный выбор. Я бы использовал либо сильно сжатый fst
формат, либо сильно сжатый, в parquet
зависимости от того, нужна ли мне компромисс между скоростью или размером файла.