如何有效地在(稀疏)矩阵中插入行?

保罗·G

我有一个庞大的稀疏矩阵,需要在特定的行索引处插入一行。我本质上应用了这里建议的技术,但这是非常低效的,因为它复制了原始矩阵。

简而言之,这是有效生成代码的范围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答案中正确地解释了这一点。:)

本·博克

我认为这应该合理有效地工作:它以稀疏(dgCMatrixdgTMatrix)格式处理基础行索引和矩阵尺寸

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章