1

我想提取数组的对角线

m=array(1:18,c(3,3,2))

我最好的镜头

k=dim(m)[3]

mn=matrix(nrow = k, ncol = 3)

for (i in 1:k){
  mn=diag(m[,,i][3:1,1:3])
  }

这将返回12 14 16,数组中第二个矩阵的反对角线。我想实现这个

[1] 3  5  7
[2] 12 14 16

我想要“anti-diags”作为数组

手动diag(m[,,1][3:1,1:3])并且diag(m[,,2][3:1,1:3])工作正常,但我正在使用的数组是dim(c(3,3,22)),所以我想“循环!”

MQ:如何使用循环从数组中提取对角线?(非常欢迎更好和优雅的解决方案)

4

2 回答 2

2

这应该有效:

mn <- array(NA, dim=dim(m))
for (i in 1:dim(m)[3]){
   mn[,,i]=diag(m[,,i][cbind(3:1,1:3)])
              }

目前尚不清楚您是否希望“反诊断”成为新的诊断,但这就是您的代码所建议的意图。该表单matrix[cbind(vec1,vec2)]从矩阵中提取 (R,C) 引用的元素。

如果您不希望它们作为数组,那么这是另一种结果:

 mn <- array(NA, dim=c(2,3))
     for (i in 1:dim(m)[3]){
        mn[i,]=m[,,i][cbind(3:1,1:3)]
                            }
 mn
     [,1] [,2] [,3]
[1,]    3    5    7
[2,]   12   14   16

这是获取相同值的无循环方式:

 m[cbind( rep(3:1,2), rep(1:3,2), rep(1:2,each=3)) ]
[1]  3  5  7 12 14 16
于 2013-08-21T08:52:55.537 回答
1

您可以lapply在第三维中使用并通过首先旋转矩阵(参见这个很好的答案)通过反转列顺序并取其对角线来提取对角线。基本上是这样的...

out <- lapply( 1:dim(m)[3] , function(x) diag( t( apply( m[,,x] , 2 , rev ) ) ) )
[[1]]
[1] 3 5 7

[[2]]
[1] 12 14 16

如果您需要将它们作为数组粘合在一起,请使用do.call...

do.call( rbind , out )
     [,1] [,2] [,3]
[1,]    3    5    7
[2,]   12   14   16

在这种特殊情况下,for循环会更快(对其进行基准测试),您应该使用@DWin 的答案。

我突然想到,我们可以稍微简化一下,避免使用列表和错误使用lapply(假设它m在 的范围之外可用lapply),因为我们也可以简单地apply跨越矩阵的第三维。所以我们可以apply一次旋转矩阵,然后diag像这样取每个旋转矩阵的...

rotM <- apply( m , 2:3 , rev )    
out <- t( apply( rotM , 3 , diag ) )
     [,1] [,2] [,3]
[1,]    3    5    7
[2,]   12   14   16
于 2013-08-21T09:16:48.837 回答