最快的方式读取 100,000 个 .dat.gz 文件

14 浏览
0 Comments

最快的方式读取 100,000 个 .dat.gz 文件

我有几十万个非常小的.dat.gz文件,我希望以最高效的方式将它们读入R中。我读取文件后立即进行聚合并丢弃数据,所以我不担心在接近过程结束时管理内存。我只是真的想加快速度,而瓶颈恰好是解压缩和读取数据。

每个数据集由366行和17列组成。以下是我目前所做的可重现示例:

构建可重现的数据:

require(data.table)
# 创建目录
system("mkdir practice")
# 创建数据的函数
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))    
}

以下是应用代码:

# 应用函数创建10个虚假的压缩数据框(磁盘上为550 kb)
tmp <- lapply(paste0("dt", 1:10,".dat"), function(x) create_write_data(x))

以下是我迄今为止读取数据的最高效代码:

# 尽可能快速地读取文件的函数
read_Fast <- function(path.gz) {
  system(paste0("gzip -d ", path.gz)) # 解压文件
  path.dat <- gsub(".gz", "", path.gz)
  dat_run <- fread(path.dat)
}
# 应用上述函数
dat.files <- list.files(path="./practice", full.names = TRUE)
system.time(dat.list <- rbindlist(lapply(dat.files, read_Fast), fill=TRUE))
dat.list

我已经将其封装成一个函数并在并行中应用,但对于我的需求来说,它仍然太慢了。

我已经尝试过来自精彩的h2o包的h2o.importFolder,但与使用纯Rdata.table相比,实际上要慢得多。也许有一种方法可以加快文件的解压缩速度,但我不确定。从我运行这个函数的几次经验来看,解压缩文件通常需要大约三分之二的函数时间。

0
0 Comments

原因:文章提到了一种方法可以快速读取100,000个.dat.gz文件,这引起了读者的兴趣和好奇心,想了解这个方法背后的原理和效率如何。

解决方法:文章中给出了一个使用命令行的解决方法,通过使用cat、gunzip、head和grep等命令来读取和处理压缩文件。通过这种方法,可以在较短的时间内读取和处理大量的文件,相比之前的方法大大提高了效率。

文章中的代码使用了fread函数来读取文件,并通过cat、gunzip和grep命令来解压缩和处理文件。首先使用fread函数读取第一个文件的列名,然后使用cat、gunzip和grep命令将所有文件解压缩并过滤掉第一行的标题行,最后将解压缩和处理后的数据赋值给tbl变量,并使用setnames函数将列名设置为之前读取的列名。

读者对这种方法的反馈非常积极,认为通过这种方法可以更快地读取和处理数据。有读者使用8个核心,只用了1.5分钟就能读取和处理696,000个文件,而以前需要12分钟。读者还表示会尝试将这种方法应用到数百万个文件的读取和处理中。

读者还对代码中的grep -v "^Day"部分提出了疑问。文章中的回答是,这部分代码的作用是移除每个文件中的第一行(标题行)。这是一种简单粗暴的方法,但在大多数情况下是可行的,特别是当第一列是数字类型时。'^'是一个锚点,它表示“移除所有第一行前三个字符为Day的行”。

通过这种方法,读者可以更快地读取和处理大量的压缩文件,提高工作效率。这种方法的有效性和效率可以通过与其他读取压缩文件的方法进行比较来进一步验证。读者对这种方法的好奇心和期待也体现了对工作效率提升的追求。

0
0 Comments

问题出现的原因是使用system()调用外部应用程序,可能导致瓶颈。

解决方法是尝试使用内置函数来提取存档。可以参考以下方法:Decompress gz file using R

以下是解决问题的方法:

首先,需要使用R语言中的内置函数来解压缩.gz文件。可以使用R的gzip包来完成这个任务。可以按照以下步骤来处理:

1. 首先,需要安装gzip包。可以使用以下命令来安装:

install.packages("gzip")

2. 安装完毕后,可以使用以下代码来解压缩.gz文件:

library(gzip)

gzfile <- "your_file.dat.gz" # 替换成你的.gz文件路径

output_file <- "your_output_file.dat" # 替换成你想要输出的文件路径

gzcon <- gzfile(gzfile, "rb")

con <- file(output_file, "wb")

while(length(data <- gzcon(1E5)) > 0) {

writeBin(data, con)

}

close(gzcon)

close(con)

以上代码将读取.gz文件并将其解压缩到指定的输出文件中。你需要将"your_file.dat.gz"替换为你的.gz文件路径,并将"your_output_file.dat"替换为你想要输出的文件路径。

通过使用R的内置函数来解压缩.gz文件,可以避免使用system()调用外部应用程序的瓶颈,从而提高读取100,000个.dat.gz文件的速度。

0
0 Comments

问题的出现原因是需要读取大量的.gz文件,但是读取速度较慢,需要寻找更快的解决方法。

解决方法是使用R语言的gzfile函数来读取.gz文件,可以使用rbindlist和lapply函数来简化代码,并提高读取速度。使用这种方法可以将读取时间从18分钟减少到12分钟。然而,仍然需要进一步提高读取速度。

整理成一篇文章如下:

R语言中快速读取100,000个.dat.gz文件的方法

在R语言中,可以使用gzfile函数来原生地读取.gz文件。可以尝试使用以下代码来实现:

rbindlist(lapply(dat.files, function(f) {
    read.delim(gzfile(f))
}))

值得一提的是,你还可以简化代码为以下形式:rbindlist(lapply(dat.files, read.delim))。这种方法似乎比read_tsv函数更快。

这确实帮助了很多。现在我能够在12分钟内读取232,000个文件,而不是18分钟。虽然如此,我仍然需要进一步提高读取速度,但这已经是一个很好的开始。

0