3D阵列的对角线

时间:2016-05-10 22:47:03

标签: r multidimensional-array

如何从R中的三维数组中提取“对角线”?对于矩阵(2D阵列),可以使用 // Delegate methods func scrollViewDidScroll(scrollView: UIScrollView) { if (scrollView.contentOffset.y <= (scrollView.frame.height PAGE_NUMBER - OFFSET_MARKER) { // Where PAGE_NUMBER is the current page, and OFFSET_MARKER is the amount of pixels to trigger at, i.e. 80px // Temporarily stop further user interaction scrollView.userInteractionEnabled = false // Reset the pan gesture recogniser -- THIS CAUSES 'SKIPPING' OF ANIMATION scrollView.panGestureRecognizer.enabled = false scrollView.panGestureRecognizer.enabled = true // I have tried both 'animated: true / false' UIView.animateWithDuration(0.4, animations: { scrollView.setContentOffset(CGPointMake(0, self.frame.height), animated: true) }, completion: { (complete) in if complete{ // Re-enable user interaction (more touches) scrollView.userInteractionEnabled = true } }) } } 函数。以类似的方式,给定N×N×M阵列,自然操作是通过从每个N×N切片获取对角线并将其作为矩阵返回来将其转换为N×M矩阵。

使用循环很容易做到这一点,但这不是惯用的R而且很慢。另一种可能性是使用稍微复杂的索引(参见我自己对这个问题的回答),但它有点难以阅读。有什么其他选择吗?是否有标准的R方式来做到这一点?

5 个答案:

答案 0 :(得分:4)

创建一个数组并用一些值填充它:

> a=array(0,c(10,10,5))
> for (i in 1:10) for (j in 1:10) for (k in 1:5) a[i,j,k]=100*i+10*j+k-111

运行apply功能:

> apply(a,3,diag)
      [,1] [,2] [,3] [,4] [,5]
 [1,]    0    1    2    3    4
 [2,]  110  111  112  113  114
 [3,]  220  221  222  223  224
 [4,]  330  331  332  333  334
 [5,]  440  441  442  443  444
 [6,]  550  551  552  553  554
 [7,]  660  661  662  663  664
 [8,]  770  771  772  773  774
 [9,]  880  881  882  883  884
[10,]  990  991  992  993  994

答案 1 :(得分:3)

各种对角线:

A = array(1:12, c(2, 2, 3))

apply(A, 1, diag)
#     [,1] [,2]
#[1,]    1    2
#[2,]    7    8
apply(A, 2, diag)
#     [,1] [,2]
#[1,]    1    3
#[2,]    6    8
apply(A, 3, diag)
#     [,1] [,2] [,3]
#[1,]    1    5    9
#[2,]    4    8   12

答案 2 :(得分:2)

虽然我并不喜欢这个术语&#34; 3d.diagonal&#34;对于这个结果,它可以通过这个简单的函数实现(直到标识模数转置):

arr <- array(1:27,c(3,3,3)  )
apply(arr, 3, function(x) x[row(x)==col(x)] )
# returns same value as diag.3d (arr)
     [,1] [,2] [,3]
[1,]    1   10   19
[2,]    5   14   23
[3,]    9   18   27

我认为真正的对角线&#34;将是arr[ cbind(1:3,1:3,1:3) ]

答案 3 :(得分:1)

一种可能的方法是使用索引,其中索引是具有三列的矩阵。例如:

diag.3d <- function(A) {
  # Expect a N x N x M array

  stopifnot(length(dim(A)) == 3)
  n <- nrow(A)
  stopifnot(n == ncol(A))
  m <- dim(A)[3]

  IXS <- cbind(1:n, 1:n, rep(1:m, each = n))
  cn <- colnames(A)
  rn <- dimnames(A)[[3]]
  matrix(A[IXS], ncol = n, byrow = T, dimnames = list(rn, cn))
}

虽然索引(变量IXS)似乎难以阅读。

答案 4 :(得分:0)

另一种方法是用2维矩阵将3维数组子集化:

a <- array(1:100,dim = c(5,5,4))
ref <- cbind(1:5,1:5,rep(1:4,each= 5))
a[ref]

输出是向量而不是矩阵。在我的计算机上,它比apply()更有效率,您还可以填充对角线值。