【问题标题】:Fast way to calculate product over one dimension of a 3D array in R在 R 中计算一维 3D 数组的乘积的快速方法
【发布时间】:2016-01-15 09:19:18
【问题描述】:

我有一个三维数组(例如维度 = 4000 x 4000 x 2)。现在我想计算第三维的乘积以获得二维数组(维度 = 4000 x 4000)作为结果。

我尝试在apply() 函数中使用prod() 计算乘积;但是,这非常耗时。因此,我想知道是否有更快更有效的方法来进行此类计算?

apply() 方法:

A <- array(runif(4000*4000*2),dim=c(4000,4000,2))
system.time(apply(A, c(1,2), prod))

这里是数组B的小例子:

B <- array(c(1,2,1,2,3,4,3,4),dim=c(2,2,2))

结果B_res:

B_res <-  array(c(3,3,8,8),dim=c(2,2))

更新: 正如@42 所述,这可以通过元素(手动)乘法来完成,例如:B_res &lt;- B[,,1]*B[,,2]。但是,第三维的大小可能在 2 到 x 之间。所以手动编码B[,,1]*B[,,2]... *B[,,x] 可能不可行。这里循环计算可能是一种可能的解决方案:

array_prod <- function(C){
  C_res <- C[,,1]
  for(i in 2:dim(C)[3]){
    C_res <- C_res*C[,,i]
  }
  return(C_res)
}

这里是三种方法的比较(应用、手动逐元素和循环乘法):

A <- array(runif(400*400*10),dim=c(400,400,10))
system.time(apply(A, c(1,2), prod)); system.time(A[,,1]*A[,,2]*A[,,3]*A[,,4]*A[,,5]*A[,,6]*A[,,7]*A[,,8]*A[,,9]*A[,,10]); system.time(array_prod(A))
  user  system elapsed 
  0.492   0.021   0.512 
   user  system elapsed 
  0.031   0.000   0.032 
   user  system elapsed 
  0.032   0.001   0.032 

...这表明 apply 函数明显慢于其他两种基本上同样快的方法。

【问题讨论】:

  • 您应该发布一个 3x3x2 数组的示例,并说出正确的答案可能是什么。如果它只是按元素 mult,那么只需 A[,,1]*A[,,2]

标签: arrays r performance multidimensional-array multiplication


【解决方案1】:

这表明元素数组乘法是使用 R 中所谓的向量化方法完成的,方法是将前两个维度留空并使用 * 运算符。也可以用 TRUE 表示特定维度的所有实例:

A <- array( 1:(4*4*2),dim=c(4,4,2))
apply(A, c(1,2), prod)
#============
     [,1] [,2] [,3] [,4]
[1,]   17  105  225  377
[2,]   36  132  260  420
[3,]   57  161  297  465
[4,]   80  192  336  512
#=============
A[ , , 1]*A[ , , 2]
     [,1] [,2] [,3] [,4]
[1,]   17  105  225  377
[2,]   36  132  260  420
[3,]   57  161  297  465
[4,]   80  192  336  512

这表明性能提高了 100 倍(虽然我厌倦了等待 4000x4000 版本的 apply 运行,所以我只在该示例中显示使用矢量化方法的结果:)

> A <- array(runif(400*400*2),dim=c(400,400,2))
> system.time(apply(A, c(1,2), prod)); system.time(A[,,1]*A[,,2])
   user  system elapsed 
  0.448   0.018   0.452   # the apply timings
   user  system elapsed 
  0.005   0.000   0.004   # the vectorised operation

> A <- array(runif(4000*4000*2),dim=c(4000,4000,2))
>  system.time(A[,,1]*A[,,2])
   user  system elapsed 
  0.525   0.096   0.604 

【讨论】:

    猜你喜欢
    • 2014-11-12
    • 2015-11-20
    • 2012-02-13
    • 1970-01-01
    • 2016-07-09
    • 2010-12-17
    • 1970-01-01
    • 2018-06-25
    • 2016-12-29
    相关资源
    最近更新 更多