【问题标题】:How to apply multicores when using sapply?使用 sapply 时如何应用多核?
【发布时间】:2015-07-02 15:52:03
【问题描述】:
R 3.1.2
library(RcppRoll)

我的数据框架

y=
  V1 V2 V3 V4 V5 V6 V7 V8 V9 
1  1  2  3  4  5  6  7  8  9  
2 16 17 18 19 20 21 22 23 24 
3 31 32 33 34 35 36 37 38 NA  
4 46 47 48 49 50 51 52 53 54  

我的功能:

    sapply(y, RcppRoll::roll_mean, n = 3, na.rm = T)

我没有问题并且工作正常,但是使用我的大量数据时它非常慢。我想知道我们如何使用多核甚至使用 for 循环来提高 sapply 的性能?

@Khashaa 是的,我试过了,速度更快,但输出有问题:

输出:

> 
      [,1] [,2] [,3] 
[1,]   16   17   18 

这会导致我的其余代码出现问题,所以我想更改为:

       V1 V2 V3
[1,]   16 17 18

对此有任何想法吗?

【问题讨论】:

  • 查看 foreach 包或使用 plyr 包中的 laply 函数,使用 foreach 提供的并行后端并行应用函数
  • 我建议在 Rcpp 中的列上实现循环。如果您仍然需要并行化,您也可以在 C++ 级别进行(例如,参见 RcppParallel)。
  • @Barry 第一步是阅读相关文档和教程(顺便说一句。我会将你的 data.frame 设为矩阵)。

标签: r


【解决方案1】:

在此特定示例中,您不需要sapply。只需roll_mean(as.matrix(y), 3, na.rm=T) 就足够了

y <- runif(1e7) 
dim(y) <- c(1e3, 1e4)
y <- data.frame(y)
system.time(sapply(y, RcppRoll::roll_mean, n = 3, na.rm = T))
#   user  system elapsed 
# 14.120   0.451  18.960 
system.time(RcppRoll::roll_mean(as.matrix(y), 3, na.rm=T))
#   user  system elapsed 
#  0.329   0.000   0.329 
# About 60x times faster

sapply 结果的唯一区别是colnames,您可以按如下方式进行更改

res <- RcppRoll::roll_mean(as.matrix(y), 3, na.rm=T)
colnames(res) <- colnames(y)
res
#     V1 V2 V3 V4 V5 V6 V7 V8   V9
#[1,] 16 17 18 19 20 21 22 23 16.5
#[2,] 31 32 33 34 35 36 37 38 39.0

【讨论】:

    【解决方案2】:

    这可行:

    mclapply(y, roll_mean, n=3, na.rm=TRUE, mc.cores=detectCores())
    

    或者

    laply(y, .fun=roll_mean, n=3, na.rm=TRUE, .parallel=TRUE)
    

    【讨论】:

    • 我尝试了 mclapply,但由于数据量很大,它失败了并说:the length of vector is not supported,尽管它与 mapply 一起工作得很好
    • 我认为mapply 没有并行化,所以试试laply(在plyr 包中)。
    • 谢谢我收到这个警告:In setup_parallel() : No parallel backend registered
    • 我认为您必须先使用registerDoMCregisterDoParallel。搜索设置,这很简单。它也可能是特定于操作系统的。
    猜你喜欢
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    相关资源
    最近更新 更多