【问题标题】:Read many files in parallel and extract data并行读取多个文件并提取数据
【发布时间】:2021-10-05 05:53:27
【问题描述】:

我有 1000 个json 文件。我想同时阅读它们。我有4 CPU 内核。

我有一个字符向量,其所有文件的名称如下:-

cik_files <- list.files("./data/", pattern = ".json")

并使用这个vector 加载文件并提取数据并将其添加到以下列表中:-

data <- list()

下面是提取数据的代码:-

for(i in 1:1000){
  data1 <- fromJSON(paste0("./data/", cik_files[i]), flatten = TRUE)
  if(("NetIncomeLoss" %in% names(data1$facts$`us-gaap`))){
    data1 <- data1$facts$`us-gaap`$NetIncomeLoss$units$USD
    data1 <- data1[grep("CY20[0-9]{2}$", data1$frame), c(3, 9)]
    try({if(nrow(data1) > 0){
      data1$cik <- strtrim(cik_files[i], 13)
      data[[length(data) + 1]] <- data1
    }}, silent = TRUE)
  }
}

然而,这需要相当多的时间。所以我想知道如何在 for 循环中并行运行代码。

提前致谢。

【问题讨论】:

  • 你用的是什么JSON访问包,RJSONIO、rjson还是jsonlite?
  • 在列表中使用 lapply 而不是 for 循环。 mclapply 可以从 parallell 使用来并行化。考虑使用data.table 中的fread 来读取文件。
  • @Rui Barradas,我正在使用 jsonlite。

标签: r foreach parallel-processing snow


【解决方案1】:

这是解决问题中的问题的尝试。未经测试,因为没有数据。

步骤 1

首先,将问题中的循环重写为函数。

f <- function(i, path = "./data", cik_files){
  filename <- file.path(path, cik_files[i])
  data1 <- fromJSON(filename, flatten = TRUE)
  if(("NetIncomeLoss" %in% names(data1$facts$`us-gaap`))){
    data1 <- data1$facts$`us-gaap`$NetIncomeLoss$units$USD
    found <- grep("CY20[0-9]{2}$", data1$frame)
    if(length(found) > 0){
      tryCatch({
        out <- data1[found, c(3, 9)]
        out$cik <- strtrim(cik_files[i], 13)
        out
      },
      error = function(e) e,
      warning = function(w) w)
    } else NULL
  } else NULL
}

第二步

现在加载包 parallel 并运行以下之一,具体取决于操作系统。

library(parallel)

# Not on Windows
library(jsonlite)
json_list <- mclapply(seq_along(cik_files), f, cik_files = cik_files)

# Windows
ncores <- detectCores()
cl <- makeCluster(ncores - 1L)
clusterExport(cl, "cik_files")
clusterEvalQ(cl, "cik_files")
clusterEvalQ(cl, library(jsonlite))

json_list <- parLapply(cl, seq_along(cik_files), f, cik_files = cik_files)

stopCluster(cl)

第三步

从返回列表json_list中提取数据。

err <- sapply(json_list, inherits, "error")
warn <- sapply(json_list, inherits, "warning")
ok <- !(err | warn)
json_list[ok]  # correctly read in

【讨论】:

  • 感谢@Rui Barradas,即使没有数据,您也能成功。这是完美的。
猜你喜欢
  • 2022-12-05
  • 1970-01-01
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
  • 1970-01-01
  • 2018-08-18
相关资源
最近更新 更多