我有相当大的稀疏矩阵(dgCMatrix
或dgTMatrix
,但这在这里不是很重要)。我想将一些元素设置为零
例如,我有3e4 * 3e4
矩阵,它是上三角形并且非常密集:~23%的元素不是零。 (实际上我有更大的矩阵〜1e5 * 1e5
,但它们更稀疏)所以在三元组dgTMatrix
形式中它需要大约3.1gb的RAM。
现在我想将所有低于某个阈值的元素(例如1
)设置为零。
非常天真的方法(也讨论here)将遵循:
threshold <- 1
m[m < threshold] <- 0
但是这个解决方案远非完美 - 130秒运行时(在具有足够ram的机器上,因此没有交换)而更重要的是需要~25-30gb的额外RAM 即可。
我发现的第二个解决方案(而且大部分都很开心)更有效 - 从头开始构建新矩阵:
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。
问题是 - 我们能做得更好吗?特别有趣的是,我们是否可以用较少的内存使用量来实现这一目标?如果能够执行到位,那将是完美的。
答案 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)
似乎效果很好。