在没有for循环/应用的情况下计算三维数组的rowSums

时间:2018-09-24 21:02:56

标签: r

采用数组set.seed(123) a_mtx = matrix(1:15,ncol=5) b_mtx = matrix(seq(1,5,length.out=30),ncol=5) b_array = array( b_mtx, dim = c( nrow(b_mtx), ncol(b_mtx), nrow(a_mtx) ) )

b_array

如果我想计算colSums的每个“切片”或“工作表”的每一列的总和,可以将colSums(b_array, dim = 1) # [,1] [,2] [,3] #[1,] 8.068966 8.068966 8.068966 #[2,] 13.034483 13.034483 13.034483 #[3,] 18.000000 18.000000 18.000000 #[4,] 22.965517 22.965517 22.965517 #[5,] 27.931034 27.931034 27.931034 及其维数参数使用:

rowSums

要对行总和执行相同的操作,我不能使用apply的维度参数,因为它被区别对待,所以我求助于apply(b_array, 3, rowSums) # [,1] [,2] [,3] #[1,] 13.27586 13.27586 13.27586 #[2,] 13.96552 13.96552 13.96552 #[3,] 14.65517 14.65517 14.65517 #[4,] 15.34483 15.34483 15.34483 #[5,] 16.03448 16.03448 16.03448 #[6,] 16.72414 16.72414 16.72414

apply

我希望对尺寸更大的数组执行相同的计算,以使var target = ["apple","banana","orange"]; var checkArray = ["apple","banana","pineapple"]; var containsOneCommonItem = target.some(x => checkArray.some(y => y === x));` ["apple","grape"] //returns true; ["apple","banana","pineapple"] //returns true; ["grape", "pineapple"] //returns false; 和其他for循环方法效率不高。

有没有其他真正的矢量化方法?

2 个答案:

答案 0 :(得分:1)

(我相信)关于MARGIN=的{​​{1}}(第二个)参数的默认思路是,它的意思是“减少的轴”(在聚合时……为了此处的效果而简化) )。但是,另一种查看方式是所有其他尺寸保持不变。

例如apply的有效等效项是colSums(ary),表示“保持未减小的轴1” 。 (apply(ary, 2, sum)实际上是在内部完成的,而不是colSums。)因此,要扩展“除 以外的所有轴”的逻辑,让我们为您的apply认识到保持第一轴和第三轴

b_array

与(我认为)用 n 维数组进行“列”求和的效率差不多。

修改

@markus在广泛的矩阵大小范围内使用apply(b_array, c(1,3), sum) # [,1] [,2] [,3] # [1,] 13.27586 13.27586 13.27586 # [2,] 13.96552 13.96552 13.96552 # [3,] 14.65517 14.65517 14.65517 # [4,] 15.34483 15.34483 15.34483 # [5,] 16.03448 16.03448 16.03448 # [6,] 16.72414 16.72414 16.72414 的速度更快,尽管它似乎收敛于较大的矩阵。

aperm

(我尚未测试内存使用情况。)

答案 1 :(得分:0)

另一个使用aperm

的选项
t(colSums(aperm(b_array, perm = c(2, 3, 1))))
#         [,1]     [,2]     [,3]
#[1,] 13.27586 13.27586 13.27586
#[2,] 13.96552 13.96552 13.96552
#[3,] 14.65517 14.65517 14.65517
#[4,] 15.34483 15.34483 15.34483
#[5,] 16.03448 16.03448 16.03448
#[6,] 16.72414 16.72414 16.72414