我有相当大的稀疏矩阵(dgCMatrix或dgTMatrix,但这在这里不是很重要)。我想将某些元素设置为零。
例如,我有一个3e4 * 3e4矩阵,该矩阵是上三角形,并且非常密集:〜23%的元素不是零。(实际上,我有更大的矩阵〜1e5 * 1e5,但是它们更稀疏了)因此,以三重态的dgTMatrix形式需要大约3.1gb的RAM。现在,我想将小于某个阈值(例如1)的所有元素设置为零。
非常幼稚的做法(这还讨论这里)将以下内容:
threshold <- 1
m[m < threshold] <- 0
Run Code Online (Sandbox Code Playgroud)
但是,该解决方案远非完美-130秒的运行时间(在具有足够内存的机器上,因此没有交换),更重要的是需要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)
Run Code Online (Sandbox Code Playgroud)
它需要仅〜6秒和需要5GB〜额外 RAM。
问题是-我们可以做得更好吗?尤其有趣的是,是否可以用更少的RAM使用率来做到这一点?如果能够就地执行此操作,那将是完美的。
像这样:
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 .
Run Code Online (Sandbox Code Playgroud)
您只需要ind向量的RAM 。如果要避免这种情况,则需要一个循环(可能在Rcpp中是为了提高性能)。