【问题标题】:R Matrix. Set particular elements of sparse matrix to zero.R 矩阵。将稀疏矩阵的特定元素设置为零。
【发布时间】:2019-03-06 01:55:28
【问题描述】:

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

  1. 非常幼稚的方法(也讨论过here)将如下:

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

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

  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 使用来做到这一点?如果能够就地执行此操作将是完美的。

【问题讨论】:

  • 如果你只是试试m@x[m@x &lt; threshold]&lt;-0呢?
  • 这不合适,因为我们会保留零。试试str(m) - 它会有相同数量的非零元素和索引。
  • 当然,但是您随后会相应地调整ij 插槽,就像@Roland 的回答一样。
  • 谢谢!出于某种原因,我自己没有猜​​到这样的把戏:-)

标签: r sparse-matrix


【解决方案1】:

像这样:

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。这也应该减小矩阵的大小。一点改进是更改ind &lt;- m@x &gt; threshold,然后用ind而不是!ind进行子集化,以节省一些RAM。
【解决方案2】:

刚刚遇到这个问题。

Matrix包中包含drop0()函数,使用如下:

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

这似乎运作良好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-19
    • 2012-01-09
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多