在R中将与矩阵对角线平行的矩阵的一些条目归零

时间:2014-08-05 07:16:15

标签: r matrix

在R中我想将矩阵的所有条目设置为零,以及矩阵对角线上方(和下方)的几个条目。对于N = 5的N×N矩阵,下面的例子我们删除平行于矩阵对角线的k = 3行条目:

a1 b1 c1 d1 e1 -->      a1  b1 00 00 00  
b2 a2 b2 c2 d2 -->      b2  a2 b2 00 00  
c3 b3 a3 b3 c3 -->      00  b3 a3 b3 00  
d4 c4 b4 a4 b4 -->      00  00 b4 a4 b4  
e5 d5 c5 b5 a5 -->      00  00 00 b5 a5  

(00 means the same as 0)

对于k = 2我们有

a1 b1 c1 d1 e1 -->      a1 b1 c1 00 00  
b2 a2 b2 c2 d2 -->      b2 a2 b2 c2 00  
c3 b3 a3 b3 c3 -->      c3 b3 a3 b3 c3  
d4 c4 b4 a4 b4 -->      00 c4 b4 a4 b4  
e5 d5 c5 b5 a5 -->      00 00 c5 b5 a5  

我已经基于两个连续的for()循环编写了简单的函数,但是如果我处理大量的小矩阵,这个函数太慢了,所有矩阵都是N x N,其中N在400:450范围内, k总是在350:370的范围内,所有矩阵条目都在-1和1之间(我处理相关矩阵),数据量是几GB,所以我需要一些矢量化的函数版本。将条目设置为零或将选择的条目复制到新矩阵是否更快?

2 个答案:

答案 0 :(得分:2)

https://stackoverflow.com/a/13049778/602276

的答案为基础

试试这个:

mat <- matrix(rnorm(25), nrow=5)

offDiagonal <- function(x, offset=1, diagonal=TRUE){
  off <- (row(x) == (col(x) - offset) | row(x) == (col(x) + offset))  
  if(diagonal) diag(off) <- TRUE
  off
}


mat[!offDiagonal(mat)] <- 0
mat

          [,1]       [,2]       [,3]       [,4]        [,5]
[1,] -2.788105 -0.8399604  0.0000000  0.0000000  0.00000000
[2,]  1.194179 -0.6940815  0.3340976  0.0000000  0.00000000
[3,]  0.000000  0.2256085  0.8885540 -0.3661173  0.00000000
[4,]  0.000000  0.0000000 -1.8024987 -0.1903742 -0.65395419
[5,]  0.000000  0.0000000  0.0000000 -0.4074090  0.08818081

使用offset参数指定更宽的非对角线波段:

mat <- matrix(rnorm(25), nrow=5)
mat[!offDiagonal(mat, offset=2)] <- 0
mat

          [,1]       [,2]       [,3]      [,4]       [,5]
[1,] 0.4433126  0.0000000  1.0448629 0.0000000  0.0000000
[2,] 0.0000000 -0.2439675  0.0000000 0.1703401  0.0000000
[3,] 0.2859253  0.0000000 -0.7731495 0.0000000 -0.1722833
[4,] 0.0000000  1.1120145  0.0000000 1.0412452  0.0000000
[5,] 0.0000000  0.0000000  1.0860853 0.0000000 -0.3957575

答案 1 :(得分:2)

set.seed(42)
d <- matrix(rnorm(25), nrow=5)


zero.them<-function(x, n){
  x2<-x
  diag(x)<-0
  for(i in 1:n){
    diag(x[,(-1:-i)])<-0
    diag(x[(-1:-i),])<-0
    }
  x2[which(x==x2)] <- 0
  return(x2)
}

zero.them(d, 1) # for 1 above and below the diagonal

           [,1]        [,2]       [,3]      [,4]     [,5]
[1,]  1.3709584 -0.10612452  0.0000000  0.000000 0.000000
[2,] -0.5646982  1.51152200  2.2866454  0.000000 0.000000
[3,]  0.0000000 -0.09465904 -1.3888607 -2.656455 0.000000
[4,]  0.0000000  0.00000000 -0.2787888 -2.440467 1.214675
[5,]  0.0000000  0.00000000  0.0000000  1.320113 1.895193

zero.them(d, 2) # for 2 above and below the diagonal

           [,1]        [,2]       [,3]       [,4]       [,5]
[1,]  1.3709584 -0.10612452  1.3048697  0.0000000  0.0000000
[2,] -0.5646982  1.51152200  2.2866454 -0.2842529  0.0000000
[3,]  0.3631284 -0.09465904 -1.3888607 -2.6564554 -0.1719174
[4,]  0.0000000  2.01842371 -0.2787888 -2.4404669  1.2146747
[5,]  0.0000000  0.00000000 -0.1333213  1.3201133  1.8951935