如何解决将函数应用于返回原始维数的数组
使用此示例数组:
set.seed(1)
rows <- 5
cols <- 4
dept <- 3
a <- array(sample(1:100,rows*cols*dept),dim = c(rows,cols,dept))
返回
> a,1
[,1] [,2] [,3] [,4]
[1,] 68 43 85 73
[2,] 39 14 21 79
[3,] 1 82 54 37
[4,] 34 59 74 83
[5,] 87 51 7 97,2
[,] 44 96 72 99
[2,] 84 42 80 91
[3,] 33 38 40 75
[4,] 35 20 69 6
[5,] 70 28 25 24,3
[,] 32 22 100 50
[2,] 94 92 62 65
[3,] 2 90 23 11
[4,] 45 98 67 17
[5,] 18 64 49 36
对于每个“部门”维度,我想获取行的总和,同时保留数组的原始三个维度。我尝试过
b <- apply(a,c(2,3),sum)
> b
[,3]
[1,] 229 266 191
[2,] 249 224 366
[3,] 241 286 301
[4,] 369 295 179
给出正确的结果,但将其减少为4 x 3的矩阵,因为行维折叠为1,不再严格需要。但是,对于我的计算而言,每次执行操作时尺寸解释都会发生变化,因此,我想获取一个1x4x3数组来代替:
c <- array(b,dim = c(1,4,3))
> c,] 229 249 241 369,] 266 224 286 295,] 191 366 301 179
这完成了我想要的,但是我认为这有点麻烦,并且我不确定如何将其推广到任意数量的维度上的不同操作。必须有一种更紧凑的方式来执行这些操作。我找到了``rray`包,但是与R 4.0.2不兼容。请注意,我的实际数组比该示例大得多,在数值优化问题中我将不得不多次应用这些类型的运算,因此计算效率非常重要。
解决方法
要概括计算并将结果保持在一行中,可以执行以下操作:
array(apply(a,2:3,sum),c(1,dim(a)[-1]))
#,1
#
# [,1] [,2] [,3] [,4]
# [1,] 229 249 241 369
#
#,2
#
# [,] 266 224 286 295
#
#,3
#
# [,] 191 366 301 179
或者,由于它是矢量化的,因此要快得多,因此可以使用colSums
array(colSums(a,dims=1),] 191 366 301 179
基准:
set.seed(42)
A <- array(rnorm(5e4*100*10),dim=c(5e4,100,10))
library(rray)
microbenchmark::microbenchmark(apply=array(apply(A,dim(A)[-1])),colSums=array(colSums(A,rray_sum=rray_sum(A,1)) ## rray: see other answer
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# apply 1273.51152 1381.72037 1416.33429 1395.84693 1433.72407 1848.88436 100 b
# colSums 72.07086 73.02890 73.85052 73.63013 74.38916 79.70227 100 a
# rray_sum 71.46261 72.50294 73.27564 73.00747 73.70348 80.36409 100 a
,
我能够使用{p> 1包的R4.0兼容版本来暂停
id Column Value
0 X1 A 1
1 X2 A 2
2 X3 A 3
3 X4 A 4
4 X1 B 5
5 X2 B 6
6 X3 B 7
7 X4 B 8
8 X1 C 9
9 X2 C 10
10 X3 C 11
11 X4 C 12
12 X1 D 12
13 X2 D 14
14 X3 D 15
15 X4 D 16
然后使用
即可达到所需的结果(快得多)rray
基准代码:
remotes::install_github("r-lib/rray")
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。