在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,所以我需要一些矢量化的函数版本。将条目设置为零或将选择的条目复制到新矩阵是否更快?
答案 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