【问题标题】:How paralellize a loop for (i in 1:100) with doParallel package如何使用 doParallel 包并行化循环 for (i in 1:100)
【发布时间】:2018-07-30 23:55:16
【问题描述】:

我的脚本中有一个复杂的循环,女巫需要太多时间才能结束(超过 1 小时)。如果可能的话,我想使用超过 1 个 CPU 内核来减少计算时间。

是否可以使用并行化来使用我的循环?

一般数据帧

TabR1

带有代码的向量,用于选择每个站点

vecsandre

功能

copy <- function (m) {
  for (i in 1:m) {
    TEST[[i]] <- TabR1[TabR1$CdStationMesureEauxSurface == vecsandre[i],]
  }
}

列表以获取选择

TEST=list()

library(doParallel)
no_cores <- detectCores() - 1
grappe <- makeCluster(no_cores)
registerDoParallel(no_cores)
system.time(foreach(z=1:10) %dopar% copy(z))
stopCluster(grappe)

我试试这个,但我得到一个错误:

copy(z) 中的错误:任务 1 失败 - “objet 'TEST' introuvable”

【问题讨论】:

标签: r doparallel


【解决方案1】:

这是一种矢量化方法 - iris 作为最小可重现示例

keep_vec <- c("setosa", "versicolor")
split_df <- split(iris, iris$Species)
keep_dfs <- split_df[keep_vec]

# $setosa
   # Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1           5.1         3.5          1.4         0.2  setosa
# 2           4.9         3.0          1.4         0.2  setosa
# 3           4.7         3.2          1.3         0.2  setosa
# ...
# $versicolor
    # Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
# 51           7.0         3.2          4.7         1.4 versicolor
# 52           6.4         3.2          4.5         1.5 versicolor
# 53           6.9         3.1          4.9         1.5 versicolor

用你的数据,试试

vecsandre
split_df <- split(TabR1, TabR1$CdStationMesureEauxSurface)
keep_dfs <- split_df[vecsandre]

【讨论】:

    【解决方案2】:

    在 R 中,foreach 循环与 for 循环的工作方式不同。考虑一下:

    > x = for (i in 1:3) {i^2}
    > x
    NULL
    > y = foreach(i = 1:3) %do% {i^2}
    > y
    [[1]]
    [1] 1
    
    [[2]]
    [1] 4
    
    [[3]]
    [1] 9
    

    for 循环不返回任何内容。它只是在{} 内重复表达式给定的次数。捕获这些迭代的结果取决于您。

    foreach 循环更像是一个函数。循环的每次迭代都返回{} 中表达式的结果(如果有多个,则返回最后一个表达式)。那么foreach 的默认行为是将每次迭代的结果组合到一个列表中并返回该列表。您不能将来自foreach 迭代的中间结果分配给另一个对象,因为foreach 的存在是为了在(可能)不同的过程中运行每个迭代。这种行为可以避免并发访问结果容器的问题,for 没有这个问题,因为它是顺序的。

    【讨论】:

    • 如果我理解得很好,当我使用 Foreach 循环时,无法更改初始数据帧,因为我们将拥有对这个唯一 df...(并行)的多重访问权限。但是当您使用 list() 时,它几乎相同,当每个进程结束时,它会将结果写入.... 没有办法修改唯一的数据帧?感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多