我正在R和MATLAB上使用多维数组,这些数组有五个维度(总共14.5M个元素)我不得不去掉一个维度,在上面加上一个算术平均值,我发现使用这两个软件的性能有惊人的差异。
MATLAB软件:

>> a = rand([144  73  10   6  23]);
>> tic; b = mean(a,3); toc
Elapsed time is 0.014454 seconds.

R:
> a = array(data = runif(144*73*6*23*10), dim = c(144,73,10,6,23))
> start <- Sys.time (); b = apply(a, c(1,2,4,5), mean); Sys.time () - start
Time difference of 1.229083 mins

我知道apply函数很慢,因为它类似于一个通用函数,但我不知道如何处理这个问题,因为这种性能差异对我来说确实是一个很大的限制我试图寻找colMeans/rowMeans函数的泛化,但没有成功。
编辑
我将展示一个小样本矩阵:
> dim(a)
[1] 2 4 3
> dput(aa)
structure(c(7, 8, 5, 8, 10, 11, 9, 9, 6, 12, 9, 10, 12, 10, 14,
12, 7, 9, 8, 10, 10, 9, 8, 6), .Dim = c(2L, 4L, 3L))
a_mean = apply(a, c(2,3), mean)
> a_mean
     [,1] [,2] [,3]
[1,]  7.5  9.0  8.0
[2,]  6.5  9.5  9.0
[3,] 10.5 11.0  9.5
[4,]  9.0 13.0  7.0

编辑(2):
我发现应用求和函数然后除以移除维度的大小肯定更快:
> start <- Sys.time (); aaout = apply(aa, c(1,2,4,5), sum); Sys.time () - start
Time difference of 5.528063 secs

最佳答案

mean特别慢,因为S3方法调度这样更快:

set.seed(42)
a = array(data = runif(144*73*6*23*10), dim = c(144,73,10,6,23))

system.time({b = apply(a, c(1,2,4,5), mean.default)})
# user  system elapsed
#16.80    0.03   16.94

如果不需要处理NAs,可以使用内部函数:
system.time({b1 = apply(a, c(1,2,4,5),  function(x) .Internal(mean(x)))})
# user  system elapsed
# 6.80    0.04    6.86

供比较:
system.time({b2 = apply(a, c(1,2,4,5),  function(x) sum(x)/length(x))})
# user  system elapsed
# 9.05    0.01    9.08

system.time({b3 = apply(a, c(1,2,4,5),  sum)
             b3 = b3/dim(a)[[3]]})
# user  system elapsed
# 7.44    0.03    7.47

(注意所有的时间都是近似的。正确的基准测试需要以重复的方式运行,例如,使用一个bechmarking包但我现在还没有足够的耐心。)
可以通过Rcpp实现来加速这一过程。

07-24 09:52
查看更多