将所有对角矢量排列在特定矩阵中

时间:2017-03-27 19:34:53

标签: r matrix

我试图弄清楚如何创建一个新的矩阵,所有对角线都按列排列。例如说我有以下矩阵

0 1 2 7 0 0 0 0
0 0 3 6 7 0 0 0
0 0 0 3 1 7 0 0
0 0 0 0 4 4 7 0
0 0 0 0 0 5 8 7
0 0 0 0 0 0 1 8
0 0 0 0 0 0 0 4
0 0 0 0 0 0 0 0

从我们得到的对角线中提取,

1 3 3 4 5 1 4
2 6 1 4 8 8
7 7 7 7 7    

现在,我正在寻找R中的有效解决方案来排列这些对角矢量,使得得到的矩阵

1 2 7  
3 6 7 
3 1 7 
4 4 7 
5 8 7 
1 8 0
4 0 0
0 0 0

此外,为了实现反向形式,即像这样的最小对角线

0 0 0
0 0 1
0 2 3
7 6 3
7 1 4
7 4 5
7 8 1
7 8 4

我尝试过使用for循环,但该解决方案的计算效率不高,因为矩阵可能很大(10 ^ 3) 我觉得有效的解决方案会非常简单,但我无法弄清楚。

2 个答案:

答案 0 :(得分:2)

您可以连续对矩阵进行子集化并提取对角元素

sapply(0:2, function(i)
            diag(m[-(nrow(m):(nrow(m)-i)), -(1:(1+i))])[1:nrow(m)] )
#     [,1] [,2] [,3]
#[1,]    1    2    7
#[2,]    3    6    7
#[3,]    3    1    7
#[4,]    4    4    7
#[5,]    5    8    7
#[6,]    1    8   NA
#[7,]    4   NA   NA
#[8,]   NA   NA   NA

OR

m2 = t(m)[which(t(m) != 0)]
m2 = append(m2, m2[length(m2)])
m2[length(m2) - 1] = NA
m2[(length(m2)+1):(NROW(m)*3)] = NA
matrix(m2, ncol = 3, byrow = TRUE)
#     [,1] [,2] [,3]
#[1,]    1    2    7
#[2,]    3    6    7
#[3,]    3    1    7
#[4,]    4    4    7
#[5,]    5    8    7
#[6,]    1    8   NA
#[7,]    4   NA   NA
#[8,]   NA   NA   NA

数据

m = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 
3, 0, 0, 0, 0, 0, 0, 7, 6, 3, 0, 0, 0, 0, 0, 0, 7, 1, 4, 0, 0, 
0, 0, 0, 0, 7, 4, 5, 0, 0, 0, 0, 0, 0, 7, 8, 1, 0, 0, 0, 0, 0, 
0, 7, 8, 4, 0), .Dim = c(8L, 8L))

答案 1 :(得分:0)

我认为最简单的方法是使用sparseMatrix格式,其中非零条目在对象中按行(i)和列(j)定义位置,以及它们所采用的值(x)。由此可以很容易地从对角线的列矩阵中获得。 for循环在这里也很快(呃),但也许稍微难以概括。

数据

m = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 
3, 0, 0, 0, 0, 0, 0, 7, 6, 3, 0, 0, 0, 0, 0, 0, 7, 1, 4, 0, 0, 
0, 0, 0, 0, 7, 4, 5, 0, 0, 0, 0, 0, 0, 7, 8, 1, 0, 0, 0, 0, 0, 
0, 7, 8, 4, 0), .Dim = c(8L, 8L))  

安排矩阵

b = 3  # Set width of band
n = nrow(m)

library(Matrix)

sm <- as(m, "TsparseMatrix") 

sparseMatrix(i = sm@i+1,
             j = sm@j - sm@i,
             x = sm@x,
             dims = c(nrow(sm),b))
#8 x 3 sparse Matrix of class "dgCMatrix"

#[1,] 1 2 7
#[2,] 3 6 7
#[3,] 3 1 7
#[4,] 4 4 7
#[5,] 5 8 7
#[6,] 1 8 .
#[7,] 4 . .
#[8,] . . .

使用for循环遍历每个对角线会更快但我认为 sparseMatrix方法更为通用

 out = matrix(0, n, b)
 for(i in 1:b) {
        ro = 1:(n-i)
        co = (1+i):n
        out[ro, i] = m[cbind(ro, co)]
  }
  out
#     [,1] [,2] [,3]
#[1,]    1    2    7
#[2,]    3    6    7
#[3,]    3    1    7
#[4,]    4    4    7
#[5,]    5    8    7
#[6,]    1    8    0
#[7,]    4    0    0
#[8,]    0    0    0