[Перевод] Быстрая загрузка данных из файлов в R
Цель этой заметки — сравнить:
read.csv
изutils
— стандартный способ чтения csv-файлов в Rread_csv
изreadr
, который в RStudio заменил предыдущий методload
иreadRDS
изbase
, иread_feather
изfeather
иfread
изdata.table
.
Данные
Для начала сгенерируем некоторые случайные данные
set.seed(123)
df <- data.frame(replicate(10, sample(0:2000, 15 * 10^5, rep = TRUE)),
replicate(10, stringi::stri_rand_strings(1000, 5)))
и сохраним файлы на диске, чтобы оценить время загрузки. Кроме формата
csv
, еще понадобятся файлы feather
, RDS
и Rdata
.path_csv <- '../assets/data/fast_load/df.csv'
path_feather <- '../assets/data/fast_load/df.feather'
path_rdata <- '../assets/data/fast_load/df.RData'
path_rds <- '../assets/data/fast_load/df.rds'
library(feather)
library(data.table)
write.csv(df, file = path_csv, row.names = F)
write_feather(df, path_feather)
save(df, file = path_rdata)
saveRDS(df, path_rds)
Теперь проверим размеры файлов:
files <- c('../assets/data/fast_load/df.csv', '../assets/data/fast_load/df.feather', '../assets/data/fast_load/df.RData', '../assets/data/fast_load/df.rds')
info <- file.info(files)
info$size_mb <- info$size/(1024 * 1024)
print(subset(info, select=c("size_mb")))
## size_mb
## ../assets/data/fast_load/df.csv 1780.3005
## ../assets/data/fast_load/df.feather 1145.2881
## ../assets/data/fast_load/df.RData 285.4836
## ../assets/data/fast_load/df.rds 285.4837
Как видим, оба формата файлов, и
csv
, и feather
, занимают гораздо больше места на диске. Csv
— в 6 раз, а feather
— более, чем в 4 раз больше RDS
и RData
.Тест производительности
Для сравнения времени чтения в 10 раундах использовалась библиотека
microbenchmark
. Методы: - utils: read.csv
- readr: read_csv
- data.table: fread
- base: load
- base: readRDS
- feather: read_feather
library(microbenchmark)
benchmark <- microbenchmark(readCSV = utils::read.csv(path_csv),
readrCSV = readr::read_csv(path_csv, progress = F),
fread = data.table::fread(path_csv, showProgress = F),
loadRdata = base::load(path_rdata),
readRds = base::readRDS(path_rds),
readFeather = feather::read_feather(path_feather), times = 10)
print(benchmark, signif = 2)
##Unit: seconds
## expr min lq mean median uq max neval
## readCSV 200.0 200.0 211.187125 210.0 220.0 240.0 10
## readrCSV 27.0 28.0 29.770890 29.0 32.0 33.0 10
## fread 15.0 16.0 17.250016 17.0 17.0 22.0 10
## loadRdata 4.4 4.7 5.018918 4.8 5.5 5.9 10
## readRds 4.6 4.7 5.053674 5.1 5.3 5.6 10
## readFeather 1.5 1.8 2.988021 3.4 3.6 4.1 10
И победитель…
feather
! Однако, использование feather
предполагает предварительную конвертацию файлов в этот формат.Использование load
или readRDS
может улучшить производительность (второе и третье место с точки зрения скорости), хранение маленького / сжатого файла — тоже преимущество. В обоих случаях сначала придется сконвертировать ваш файл в соответствующий формат.
Что касается чтения из формата csv
, fread
значительно выигрывает у read_csv
и read.csv
, и соответственно, является лучшим вариантом для чтения из csv
-файла.
В нашем случае решили работать с feather
-файлом, поскольку конвертация из csv
в этот формат была однократной, и у нас не было строгого ограничения на размер файлов, потому мы не рассматривали форматы Rds
или RData
.
Окончательная последовательность действий была такой:
- чтение
csv
-файла, предоставленного заказчиком, с помощьюfread
, - запись этого файла в
feather
черезwrite_feather
, и - загрузка
feather
-файла при запуске приложения, используяread_feather
.
Первые две задачи были выполнены единожды и вне контекста приложения на Shiny.
Есть еще один интересный тест производительности по считыванию файлов в R. К сожалению, если использовать функции, указанные в статье, вы получите объекты строкового типа, и придется выполнить какую-то обработку строковых данных, прежде чем можно будет работать с наиболее широко и часто применяемым dataframe.
Комментарии (1)
16 апреля 2017 в 16:27
0↑
↓
Есть ещё прикольный формат — parquet. В нём данные хранятся колонками, а не строками. Размер где-то раза в 4 меньше, чем у CSV. Скорость чтения/записи существенно выше. Если нужна только часть колонок, то ещё быстрее.