使用 R 通过循环读取数据并将数据写入文件的有效方法

Nel*_*ell 5 performance r sparkr

我试图在每个时间步读取数据并将其写入文件。

\n\n

为此,我使用该包h5来存储大型数据集,但我发现使用该包的功能的代码运行缓慢。我正在处理非常大的数据集。所以,我有内存限制问题。这是一个可重现的示例:

\n\n
library(ff)\nlibrary(h5)\nset.seed(12345)\nfor(t in 1:3650){\n\n  print(t)\n\n  ## Initialize the matrix to fill\n  mat_to_fill <- ff(-999, dim=c(7200000, 48), dimnames=list(NULL, paste0("P", as.character(seq(1, 48, 1)))), vmode="double", overwrite = T) \n  ## print(mat_to_fill)\n  ## summary(mat_to_fill[,])\n\n  ## Create the output file\n  f_t <- h5file(paste0("file",t,".h5"))\n\n  ## Retrieve the matrix at t - 1 if t > 1\n  if(t > 1){\n    f_t_1 <- h5file(paste0("file", t - 1,".h5"))\n    mat_t_1 <- f_t_1["testmat"][] ## *********** ##\n    ## f_t_1["testmat"][]\n\n  } else {\n\n    mat_t_1 <- 0\n\n  }\n\n  ## Fill the matrix\n  mat_to_fill[,] <- matrix(data = sample(1:100, 7200000*48, replace = TRUE), nrow = 7200000, ncol = 48) + mat_t_1\n  ## mat_to_fill[1:3,]\n\n  ## Write data\n  system.time(f_t["testmat"] <- mat_to_fill[,]) ## *********** ##\n  ## f_t["testmat"][]\n  h5close(f_t)\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

有没有一种有效的方法来加速我的代码(参见符号## *********** ##)?任何建议将不胜感激。

\n\n

编辑

\n\n

我尝试从createDataFrame包“ SparkR”的功能创建数据框,但出现以下错误消息:

\n\n
Error in writeBin(batch, con, endian = "big") : \n  long vectors not supported yet: connections.c:4418\n
Run Code Online (Sandbox Code Playgroud)\n\n

我还测试了其他函数来在文件中写入大量数据:

\n\n
test <- mat_to_fill[,]\n\nlibrary(data.table)\nsystem.time(fwrite(test, file = "Test.csv", row.names=FALSE))\n   user  system elapsed                                                                                                              \n  33.74    2.10   13.06 \n\nsystem.time(save(test, file = "Test.RData"))\n user  system elapsed \n 223.49    0.67  224.75 \n\nsystem.time(saveRDS(test, "Test.Rds"))\n user  system elapsed \n 197.42    0.98  199.01 \n\nlibrary(feather)\ntest <- data.frame(mat_to_fill[,])\nsystem.time(write_feather(test, "Test.feather")) \n   user  system elapsed \n   0.99    1.22   10.00 \n
Run Code Online (Sandbox Code Playgroud)\n\n

如果可能的话,我想将运行时间减少到 <= 1 秒。

\n\n

补充信息

\n\n

我正在使用 R 构建基于代理的模型,但由于我使用大型 3D 数组,因此存在内存问题。在 3D 数组中,第一个维度对应于时间(每个数组有 3650 行),第二个维度定义个体或景观单元的属性(每个数组有 48 列),第三个维度代表每个个体(总共有是 720000 个个体)或景观细胞(总共有 90000 个细胞)。我总共有 8 个 3D 数组。目前,3D 数组是在初始化时定义的,以便使用多个函数在每个时间步(1 天)将数据存储在数组中。但是,要从模型中填充 t 处的一个 3D 数组,我只需将数据保留在 t \xe2\x80\x93 1 和 t \xe2\x80\x93 tf \xe2\x80\x93 1 处,其中 tf 是持续时间固定参数(例如,tf = 320 天)。但是,我不知道如何在每个时间步在 ABM 中管理这些 3D 数组。因此,我的第一个避免内存问题的解决方案是在每个时间步保存每个个体或单元格的 3D 数组中包含的数据(因此是 2D 数组),并在 t \xe2\x80 处检索数据(从而从文件中读取数据) \x93 1 和 t \xe2\x80\x93 tf \xe2\x80\x93 1。

\n

isp*_*zax 5

您的矩阵为 7200000 * 48,使用 4 字节整数,您将获得 7200000 * 48 * 4 字节或 ~1.3Gb。HDD 读写操作速度为 120Mb/s,如果您拥有普通HDD,您很幸运能够获得 10 秒的时间。有了好的SDD,您应该能够获得 2-3Gb/s,因此使用您尝试过的 fwrite 或 write_feather 大约需要 0.5 秒。我假设您没有 SDD,因为没有提及。您有 32Gb 的内存,这似乎足以容纳 8 个该大小的数据集,因此您很可能正在使用内存来复制这些数据。您可以尝试优化内存使用情况,而不是将其写入硬盘或一次处理数据集的一部分,尽管这两种方法可能都会带来实施挑战。分割数据和合并结果的问题是频繁的分布式计算,需要分割数据集,然后合并多个工作人员的结果。使用数据库总是比普通磁盘操作慢,除非它是内存数据库,并且声明不适合内存,除非您有一些可以轻松压缩/提取的非常具体的稀疏数据。