我有一个庞大的稀疏矩阵,需要在特定的行索引处插入一行。我本质上应用了这里建议的技术,但这是非常低效的,因为它复制了原始矩阵。
简而言之,这是有效生成代码的范围M2
(理想情况下,直接替换M
,因此M2
甚至不需要):
library(Matrix)
M = as(cbind(1:4,1:4),"sparseMatrix") # original sparse matrix
M # view
v = c(2,4) # row indices where new rows should be inserted
M2 = M # copy matrix to keep sparse class
for(i in 1:length(v)) M2 = rbind(M2,rep(0, ncol(M2))) # insert new rows at end
M2[-v,] = M # get each row in v 2 times ## <- THIS takes very long
M2[v,] = 0 # populate the newly inserted rows (e.g. here: 0)
M2 # view
理想情况下,我正在寻找诸如append
矢量或add_row
小标题之类的函数。
编辑:我注意到,不仅上述过程效率低下,而且不是我要找的东西,因为它在新的(结果)矩阵M2的索引2和4处添加行,而我正在寻找在索引处添加行旧(初始)矩阵的2和4 ,即现在的最终结果是:
[1,] 1 1
[2,] . .
[3,] 2 2
[4,] . .
[5,] 3 3
[6,] 4 4
即在新矩阵的索引2和索引4处添加行。我正在寻找的是:
[1,] 1 1
[2,] . .
[3,] 2 2
[4,] 3 3
[5,] . .
[6,] 4 4
也就是说,在旧矩阵的索引2和4之前添加了新行。@Ben Bolker在他的+1答案中正确地解释了这一点。:)
我认为这应该合理有效地工作:它以稀疏(dgCMatrix
或dgTMatrix
)格式处理基础行索引和矩阵尺寸。
add_rows <- function(M,v) {
oldind <- seq(dim(M)[1])-1L ## all rows (0-indexed)
## new row indices: count how many rows are inserted before a given row
## (maybe a clearer/better/more efficient way to do this?)
newind <- oldind + as.integer(rowSums(outer(oldind,v,">=")))
## modify dimensions
M@Dim <- M@Dim + c(length(v),0L)
## modify row indices (1L accounts for 0 vs 1-indexing)
M@i <- newind[M@i+1L]
M
}
最有可能成为(内存/计算)瓶颈的部分是新行索引的计算。我通过构造所有行号的索引来做到这一点。下面的版本仅对newind
占用的行进行计算,但要额外调用unique()
和match()
。
add_rows_2 <- function(M,v) {
oldind <- unique(M@i)
## new row indices
newind <- oldind + as.integer(rowSums(outer(oldind,v,">=")))
## modify dimensions
M@Dim <- M@Dim + c(length(v),0L)
M@i <- newind[match(M@i,oldind)]
M
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句