R矩阵。将稀疏矩阵的特定元素设置为零。

时间:2015-11-18 08:43:01

标签: r sparse-matrix

我有相当大的稀疏矩阵(dgCMatrixdgTMatrix,但这在这里不是很重要)。我想将一些元素设置为零 例如,我有3e4 * 3e4矩阵,它是上三角形并且非常密集:~23%的元素不是零。 (实际上我有更大的矩阵〜1e5 * 1e5,但它们更稀疏)所以在三元组dgTMatrix形式中它需要大约3.1gb的RAM。 现在我想将所有低于某个阈值的元素(例如1)设置为零。

  1. 非常天真的方法(也讨论here)将遵循:

    threshold <- 1
    m[m < threshold] <- 0
    

    但是这个解决方案远非完美 - 130秒运行时(在具有足够ram的机器上,因此没有交换)而更重要的是需要~25-30gb的额外RAM 即可。

  2. 我发现的第二个解决方案(而且大部分都很开心)更有效 - 从头开始​​构建新矩阵:

    threshold <- 1
    ind <- which(m@x > threshold)
    m <- sparseMatrix(i = m@i[ind], j = m@j[ind], x = m@x[ind], 
                 dims = m@Dim, dimnames = m@Dimnames, 
                 index1 = FALSE, 
                 giveCsparse = FALSE, 
                 check = FALSE)
    

    仅需约6秒需要~5gb额外 RAM。

  3. 问题是 - 我们能做得更好吗?特别有趣的是,我们是否可以用较少的内存使用量来实现这一目标?如果能够执行到位,那将是完美的。

2 个答案:

答案 0 :(得分:5)

像这样:

library(Matrix)
m <- Matrix(0+1:28, nrow = 4)
m[-3,c(2,4:5,7)] <- m[ 3, 1:4] <- m[1:3, 6] <- 0
(m <- as(m, "dgTMatrix"))
m
#4 x 7 sparse Matrix of class "dgTMatrix"
#
#[1,] 1 .  9 .  .  .  .
#[2,] 2 . 10 .  .  .  .
#[3,] . .  . . 19  . 27
#[4,] 4 . 12 .  . 24  .

threshold <- 5
ind <- m@x <= threshold
m@x <- m@x[!ind]
m@i <- m@i[!ind]
m@j <- m@j[!ind]
m
#4 x 7 sparse Matrix of class "dgTMatrix"
#
#[1,] . .  9 .  .  .  .
#[2,] . . 10 .  .  .  .
#[3,] . .  . . 19  . 27
#[4,] . . 12 .  . 24  .

您只需要ind向量的RAM。如果你想避免这种情况,你需要一个循环(可能在Rcpp中表示性能)。

答案 1 :(得分:1)

只是碰到了这个问题。

Matrix程序包包含drop0()函数,其用法如下:

threshold <- th
m <- drop0(m, tol = th)

似乎效果很好。