【问题标题】:Run time - using apply functions运行时 - 使用应用函数
【发布时间】:2010-09-10 15:45:36
【问题描述】:

我有两个应用函数在大型三维数组 (437216,8,3) 上执行前两个维度的平均值和标准偏差。在 Rx32 上完成需要 16 分钟。这是我们定期应用此脚本的数据库中许多大型数组中的第一个。关于如何加快运行时间的任何想法?

【问题讨论】:

  • 通常最好添加一些示例代码和 - 如果可能的话 - 数据以准确显示您正在尝试做什么。答案是:向量化代码。但是如果不知道自己在做什么,就不可能向你展示你必须如何去做。
  • 看看?rowSums?rowsum,也许还有?perm
  • 如果您在 Linux 上工作,那么这可能是一个交换问题。你有足够的内存吗?

标签: r apply


【解决方案1】:

这似乎很慢。在我的机器上

set.seed(10)

x = array(rnorm(437216*8*3), dim = c(437216,8,3))

system.time(apply(x, 1, mean))

需要

   user  system elapsed 
 23.903   0.263  24.522 

FWIW,

system.time(apply(x, 2, mean))
       user  system elapsed 
      0.546   0.274   0.841 


system.time(apply(x, 3, mean))
   user  system elapsed 
  0.516   0.267   0.790 

你的 sessionInfo() 是什么?

sessionInfo()
R version 2.11.1 (2010-05-31) 
i386-apple-darwin9.8.0 

locale:
[1] en_US.UTF-8/en_US.UTF-8/C/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
[1] cimis_0.1-3    RLastFM_0.1-4  RCurl_1.4-2    bitops_1.0-4.1 XML_3.1-0      lattice_0.18-8

loaded via a namespace (and not attached):
[1] grid_2.11.1  tools_2.11.1

【讨论】:

    【解决方案2】:

    我的systemInfo()如下:

    sessionInfo() R version 2.11.0 (2010-04-22) x86_64-pc-mingw32
    
    locale: [1] LC_COLLATE=English_United States.1252 [2] LC_CTYPE=English_United States.1252 [3] LC_MONETARY=English_United States.1252 [4] LC_NUMERIC=C [5] LC_TIME=English_United States.1252
    
    attached base packages: [1] stats     graphics  grDevices utils     datasets methods   base
    
    other attached packages: [1] abind_1.1-0   RSQLite_0.9-1 DBI_0.2-5
    

    apply 函数适用于第一个和第二个边距 (1:2) 并且系统时间低于,我相信这是导致它运行这么长时间的原因。我在更好的计算机/系统(上面列出)上运行它并减少了一些运行时间(下面),但它似乎仍然比它应该花费的时间更长:

    >  system.time(apply(x,1:2,mean))   
    user  system elapsed
    311.56    0.30  311.88
    > system.time(apply(x,1:2,sd))    
    user  system elapsed
    505.92    0.21  506.81
    

    我会考虑将其转换为 data.frame 并按照第二个建议将其取消列出。感谢大家的帮助!

    【讨论】:

    • try : 'TMP
    • @curransk :我检查了它,它的运行速度比原始代码快得多。请参阅我之前答案的编辑版本。
    • @Joris Meys -- 非常感谢,这大大加快了速度。对于一些较大的阵列,我的时间缩短到不到一分钟。我是新来的,还没有“声誉”。否则,我会给你一个大大的赞许。再次感谢!
    • @curransk : 如果您是话题发起者(Krissi?),您可以通过点击左侧的“V”符号来接受正确答案。
    【解决方案3】:

    编辑:在 OP 提供的代码之后,问题变得清晰了。诀窍是将其转换为数据框:

    > x = array(rnorm(437216*8*3), dim = c(437216,8,3))
    
    > system.time(apply(x,1:2,mean))
       user  system elapsed 
     107.06    0.18  107.34 
     # This is run on a new quadcore i7, so it's not a slow machine...
    
    > Tmp <- data.frame(V1=as.vector(x[,,1]),
    +             V2=as.vector(x[,,2]),
    +             V3= as.vector(x[,,3]))
    
    > system.time({
    +     Means <- rowMeans(Tmp)
    +     Sd <- sqrt(rowSums((Tmp-Means)^2)/(3-1))
    + })
       user  system elapsed 
       6.72    0.40    7.12 
    

    要在正确的矩阵中得到结果:

    Means <- matrix(Means,ncol=8)
    Sd <- matrix(Sd,ncol=8)
    

    概念证明:

    x = array(rnorm(10*8*3), dim = c(10,8,3))
    
    m1 <- apply(x,1:2,mean)
    sd1 <- apply(x,1:2,sd)
    
    Tmp <- data.frame(V1=as.vector(x[,,1]),
                V2=as.vector(x[,,2]),
                V3= as.vector(x[,,3]))
    m2 <- rowMeans(Tmp)
    
    sd2 <- sqrt(rowSums((Tmp-m2)^2)/2)
    
    m2 <-matrix(m2,ncol=8)
    sd2 <- matrix(sd2,ncol=8)
    
    > all.equal(m1,m2)
    [1] TRUE
    
    > all.equal(sd1,sd2)
    [1] TRUE
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-12
      • 2014-10-28
      • 2019-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多