【问题标题】:How to vectorize expanding a compressed sparse matrix from vector of column indices?如何向量化从列索引向量扩展压缩稀疏矩阵?
【发布时间】:2017-01-22 23:31:07
【问题描述】:

我想从一个向量构建一个矩阵如下:如果y的第一个元素是5,我想使矩阵的第一行和第5列为1。该行中的其他元素为0。

y=round(runif(30)*9)+1
y_m=matrix(rep(0,length(y)*10),ncol=10)
for (i in 1:length(y)){
  y_m[i,y[i]]=1;
}

有什么方法可以避免 for 循环?我试图做y_m[,y]=1,但显然它不起作用。

【问题讨论】:

  • 我认为您的意思是“从列索引向量扩展压缩稀疏矩阵”
  • 另一种方法:xtabs(rep(1, length(y)) ~ seq_along(y) + y)

标签: r vector vectorization sparse-matrix indices


【解决方案1】:

是:使用两列索引矩阵。来自?"["

当使用“[”索引数组时,单个参数“i”可以是 具有与“x”维数一样多的列的矩阵; 结果是一个向量,其元素对应于 'i' 的每一行中的索引集。

设置:

set.seed(101)
y <- round(runif(30)*9)+1

你的方式(我简化了矩阵构造):

y_m <- matrix(0,ncol=10,nrow=length(y))
for (i in 1:length(y)){
  y_m[i,y[i]] <- 1
}

通过矩阵索引:

y_m2 <- matrix(0,ncol=10,nrow=length(y))
y_m2[cbind(1:length(y),y)] <- 1

检查:

all.equal(y_m,y_m2)  ## TRUE

【讨论】:

    【解决方案2】:

    你可以使用:

    y_m[cbind(1:length(y), y)] <- 1
    

    由于您有一个稀疏矩阵,您可能需要:

    sparse_y_m <- Matrix::sparseMatrix(i = 1:length(y), j = y, x = 1)
    

    如果您想要一个完整的矩阵,请使用

    y_m <- as.matrix(sparse_y_m)
    

    【讨论】:

      【解决方案3】:

      您可以使用 xtabs 仅从 y 生成矩阵,通过行号索引传播 1 的向量,即 seq_along(y) 然后 y 本身:

      xtabs(rep(1, length(y)) ~ seq_along(y) + y)
      ##             y
      ## seq_along(y) 1 2 3 4 5 6 7 8 9 10
      ##           1  0 0 0 1 0 0 0 0 0  0
      ##           2  0 1 0 0 0 0 0 0 0  0
      ##           3  1 0 0 0 0 0 0 0 0  0
      ##           4  0 0 0 0 0 0 1 0 0  0
      ##           5  0 0 0 1 0 0 0 0 0  0
      ##           6  0 0 0 1 0 0 0 0 0  0
      ##           ...
      

      或将其设为稀疏矩阵:

      xtabs(rep(1, length(y)) ~ seq_along(y) + y, sparse = TRUE)
      ## 30 x 10 sparse Matrix of class "dgCMatrix"
      ##                       
      ## 1  . . . 1 . . . . . .
      ## 2  . 1 . . . . . . . .
      ## 3  1 . . . . . . . . .
      ## 4  . . . . . . 1 . . .
      ## 5  . . . 1 . . . . . .
      ## 6  . . . 1 . . . . . .
      ## ...
      

      或使用 data.frame 进行设置以获得更好的标签:

      xtabs(i ~ row + y, data.frame(y, i = 1, row = seq_along(y)))
      ##     y
      ## row  1 2 3 4 5 6 7 8 9 10
      ##   1  0 0 0 1 0 0 0 0 0  0
      ##   2  0 1 0 0 0 0 0 0 0  0
      ##   3  1 0 0 0 0 0 0 0 0  0
      ##   4  0 0 0 0 0 0 1 0 0  0
      ##   5  0 0 0 1 0 0 0 0 0  0
      ##   6  0 0 0 1 0 0 0 0 0  0
      ##   ...
      

      【讨论】:

      • 我试过了,data.matrix model.matrix,非常接近……谢谢!!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-05
      • 2017-03-26
      • 2019-03-12
      • 2018-04-05
      • 2020-02-28
      相关资源
      最近更新 更多