【问题标题】:replace nested for-loops on multidimensional array with mclapply()用 mclapply() 替换多维数组上的嵌套 for 循环
【发布时间】:2021-01-29 00:18:13
【问题描述】:

我正在尝试对 4 维数组执行操作。这个数组最终变得非常大,但对于我正在处理的数据来说是必要的。现在这个过程本身正在膨胀,但我想让它为并行计算做好准备。我可以访问一台 96 核的大型机,我想使用它。

到目前为止,我已经在网上阅读到完成这项工作的最简单方法是使用 mclapply(),它是 lapply() 的并行版本。我知道 lapply() 如何工作的基础知识,但我不太清楚如何在这种情况下应用它。

我有一个用 NA 填充的 4 维数组。每个维度都有暗名。我想比较维度 1 与维度 3 和维度 2 与维度 4 的暗名(这是由我编写的自定义函数完成的)。如果它们都匹配,就会出现一个数字,我希望将该数字输入 xy[i, k, j, l] 其中字母 i-l 代表一个条目的索引。

在下面的示例中,我将其简化为添加了暗名称的 nchar() 值。

xy <- array(NA, dim = c(10, 10, 10, 10), dimnames = list(c("john", "sandra", "peter", "linda", "max", "sam", "ana", "enzo", "juan", "abe"), 
                                                          c("smith", "gonzalez", "doe", "dopi", "lincoln", "biden", "rutte", "merkel", "slim", "shady"),
                                                          c("jon", "sam", "pete", "melinda", "max", "sam", "anna", "carlo", "jiro", "abel"),
                                                          c("smitty", "rupinder", "dole", "mite", "lincolan", "bidet", "rourke", "meer", "smart", "sunny")))

for(i in 1:dim(xy)[1]){
    for(j in 1:dim(xy)[3]){
      for(k in 1:dim(xy)[2]){
        for(l in 1:dim(xy)[4]){
          a <- nchar(dimnames(xy)[[1]][i]) + nchar(dimnames(xy)[[3]][j])
          b <- nchar(dimnames(xy)[[2]][k]) + nchar(dimnames(xy)[[4]][l])
          if(!is.null(a) & !is.null(b)){
            xy[i, k, j, l] <- a + b
          }
        }
      }
    }
  }

我的问题是我的输出需要是一个多维数组。到目前为止,我只使用 lapply() 来输出一个值列表。如何将其扩展到多个维度?

我已经看过这些帖子:

replace a nested for loop with mapply

replace nested foreach loops

但其中每一个都以无助于我的方式解决问题。

【问题讨论】:

    标签: r for-loop lapply mclapply


    【解决方案1】:
    fun_on_names <- function(Var1, Var2, Var3, Var4){
     
     a <- nchar(Var1) + nchar(Var3)
     b <- nchar(Var2) + nchar(Var4)
     
     if(!is.null(a) & !is.null(b)) return(a + b)
     else return(NA)
     
    }
    
    xy[] <- do.call(parallel::mcmapply, 
                    c(list(FUN = fun_on_names, mc.cores = 96),
                      expand.grid(dimnames(xy), stringsAsFactors = FALSE)))
    

    想法是:

    • 使用expand.grid 创建一个包含您拥有的所有名称组合的大数据框架。
    • 对每个组合应用函数fun_on_names
    • 将结果应用回xy

    该函数实际上返回一个数值向量,但是通过将 [] 保留在 xy[]&lt;- 中,您将通过保持 xy 的属性完整而将值分配回 xy,这使其成为一个多维数组。

    此解决方案不能在 Windows 上并行工作。

    do.call 不需要 mcapply 将 data.frame 的每一列(expand.grid 的输出)视为单独的向量。

    你可以这样看:

    df <- expand.grid(dimnames(xy), stringsAsFactors = FALSE)
    xy[] <- parallel::mcmapply(FUN = fun_on_names, 
                               mc.cores = 96,
                               df[[1]], df[[2]], df[[3]], df[[4]])
    

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 2020-06-03
      • 2018-05-21
      • 2019-06-06
      • 1970-01-01
      • 2016-07-14
      • 2021-04-05
      • 2021-08-09
      • 1970-01-01
      相关资源
      最近更新 更多