考虑数组a

> a <- array(c(1:9, 1:9), c(3,3,2))
> a
, , 1

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 2

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9


我们如何有效地计算由第三维索引的矩阵的行总和,使得结果为:

     [,1] [,2]
[1,]   12   12
[2,]   15   15
[3,]   18   18


??

通过'dims'colSums()参数可以很容易地实现列总和:

> colSums(a, dims = 1)


但是我找不到在数组上使用rowSums()的方法来获得所需结果的方法,因为它对'dims'的解释与对colSums()的解释不同。

使用以下方法计算所需的行总和很简单:

> apply(a, 3, rowSums)
     [,1] [,2]
[1,]   12   12
[2,]   15   15
[3,]   18   18


但这只是隐藏循环。还有其他高效,真正矢量化的方法来计算所需的行总和吗?

最佳答案

@Fojtasek提到的答案拆分数组使我想起了aperm()函数,该函数允许排列数组的维数。随着colSums()的工作,我们可以使用aperm()交换前两个维,并在输出上运行colSums()

> colSums(aperm(a, c(2,1,3)))
     [,1] [,2]
[1,]   12   12
[2,]   15   15
[3,]   18   18


这个和其他建议的基于R的答案的一些比较时间:

> b <- array(c(1:250000, 1:250000),c(5000,5000,2))
> system.time(rs1 <- apply(b, 3, rowSums))
   user  system elapsed
  1.831   0.394   2.232
> system.time(rs2 <- rowSums3d(b))
   user  system elapsed
  1.134   0.183   1.320
> system.time(rs3 <- sapply(1:dim(b)[3], function(i) rowSums(b[,,i])))
   user  system elapsed
  1.556   0.073   1.636
> system.time(rs4 <- colSums(aperm(b, c(2,1,3))))
   user  system elapsed
  0.860   0.103   0.966


因此,在我的系统上,aperm()解决方案的显示速度稍快一些:

> sessionInfo()
R version 2.12.1 Patched (2011-02-06 r54249)
Platform: x86_64-unknown-linux-gnu (64-bit)


但是,rowSums3d()给出的答案与其他解决方案不同:

> all.equal(rs1, rs2)
[1] "Mean relative difference: 0.01999992"
> all.equal(rs1, rs3)
[1] TRUE
> all.equal(rs1, rs4)
[1] TRUE

关于arrays - 有效地计算R中3d数组的行总和,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5135415/

10-15 01:16