У меня есть несколько сотен тысяч очень маленьких файлов .dat.gz
, которые я хочу читать в R наиболее эффективным способом. Я читаю в файле, а затем сразу агрегирую и отбрасываю данные, поэтому я не беспокоюсь об управлении памятью, когда я приближаюсь к концу процесса. Я просто хочу ускорить узкое место, которое, разумеется, распаковывается и читается в данных.Самый быстрый способ читать в 100 000 файлах .dat.gz
Каждый набор данных состоит из 366 строк и 17 столбцов. Вот воспроизводимый пример того, что я делал до сих пор:
Построение воспроизводимых данных:
require(data.table)
# Make dir
system("mkdir practice")
# Function to create data
create_write_data <- function(file.nm) {
dt <- data.table(Day=0:365)
dt[, (paste0("V", 1:17)) := lapply(1:17, function(x) rnorm(n=366))]
write.table(dt, paste0("./practice/",file.nm), row.names=FALSE, sep="\t", quote=FALSE)
system(paste0("gzip ./practice/", file.nm))
}
А вот код применения:
# Apply function to create 10 fake zipped data.frames (550 kb on disk)
tmp <- lapply(paste0("dt", 1:10,".dat"), function(x) create_write_data(x))
А вот мой самый эффективный код до сих пор для чтения в данных:
# Function to read in files as fast as possible
read_Fast <- function(path.gz) {
system(paste0("gzip -d ", path.gz)) # Unzip file
path.dat <- gsub(".gz", "", path.gz)
dat_run <- fread(path.dat)
}
# Apply above function
dat.files <- list.files(path="./practice", full.names = TRUE)
system.time(dat.list <- rbindlist(lapply(dat.files, read_Fast), fill=TRUE))
dat.list
Я запустил это в функцию и применил его в пар. allel, но он все еще слишком медленный для того, для чего мне это нужно.
Я уже попробовал h2o.importFolder
из замечательного h2o
пакета, но это на самом деле гораздо медленнее по сравнению с использованием обычного R
с data.table
. Возможно, есть способ ускорить рассылку файлов, но я не уверен. Из нескольких раз, когда я запускал это, я заметил, что распаковка файлов обычно занимает около 2/3 времени функции.
Я получаю улучшенные скорости (по сравнению с вашим самым эффективным кодом до сих пор) с помощью 'read_tsv' из пакета« readr ». 'rbindlist (lapply (dat.files, read_tsv))' – A5C1D2H2I1M1N2O1R2T1