我试图弄清楚如何创建一个新的矩阵,所有对角线都按列排列。例如说我有以下矩阵
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) 我觉得有效的解决方案会非常简单,但我无法弄清楚。
答案 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