首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从稀疏向量列表创建稀疏矩阵

从稀疏向量列表创建稀疏矩阵
EN

Stack Overflow用户
提问于 2012-01-13 07:09:02
回答 3查看 4.6K关注 0票数 4

我有一个稀疏向量列表(在R中)。我需要将这个列表转换成一个稀疏矩阵。通过for循环来做这件事需要很长时间。

代码语言:javascript
复制
sm<-spMatrix(length(tc2),n.col)
for(i in 1:length(tc2)){
    sm[i,]<-(tc2[i])[[1]];  
}

有没有更好的方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-13 07:49:42

下面是一个两步解决方案:

  • 使用lapply()as(..., "sparseMatrix")sparseVectors的列表转换为只有一列的list在单个sparseMatrix.中,
  • 使用do.call()cBind()合并sparseMatrices

代码语言:javascript
复制
require(Matrix)

# Create a list of sparseVectors
ss <- as(c(0,0,3, 3.2, 0,0,0,-3), "sparseVector")
l <- replicate(3, ss)

# Combine the sparseVectors into a single sparseMatrix
l <- lapply(l, as, "sparseMatrix")
do.call(cBind, l)

# 8 x 3 sparse Matrix of class "dgCMatrix"
#                    
# [1,]  .    .    .  
# [2,]  .    .    .  
# [3,]  3.0  3.0  3.0
# [4,]  3.2  3.2  3.2
# [5,]  .    .    .  
# [6,]  .    .    .  
# [7,]  .    .    .  
# [8,] -3.0 -3.0 -3.0
票数 8
EN

Stack Overflow用户

发布于 2015-05-07 08:06:34

这个场景,cbind一堆向量,为将信息直接转储到一个sparse, column-oriented矩阵(dgCMatrix类)做了完美的设置。

下面是一个可以做到这一点的函数:

代码语言:javascript
复制
sv.cbind <- function (...) {
    input <- lapply( list(...), as, "dsparseVector" )
    thelength <- unique(sapply(input,length))
    stopifnot( length(thelength)==1 )
    return( sparseMatrix( 
            x=unlist(lapply(input,slot,"x")), 
            i=unlist(lapply(input,slot,"i")), 
            p=c(0,cumsum(sapply(input,function(x){length(x@x)}))),
            dims=c(thelength,length(input))
        ) )
}

从快速测试来看,这看起来比强制+ cBind快大约10倍

代码语言:javascript
复制
require(microbenchmark)
xx <- lapply( 1:10, function (k) {
            sparseVector( x=rep(1,100), i=sample.int(1e4,100), length=1e4 )
        } )
microbenchmark( do.call( sv.cbind, xx ), do.call( cBind, lapply(xx,as,"sparseMatrix") ) )
# Unit: milliseconds
#                                            expr       min        lq      mean   median       uq       max neval cld
#                           do.call(sv.cbind, xx)  1.398565  1.464517  1.540172  1.49487  1.55911  3.455421   100  a 
#  do.call(cBind, lapply(xx, as, "sparseMatrix")) 16.037890 16.356268 16.956326 16.59854 17.49956 20.256253   100   b
票数 4
EN

Stack Overflow用户

发布于 2012-01-24 05:58:18

感谢Josh O‘’Brien提出的解决方案:创建3个列表,然后创建sparseMatrix。我在这里包含了代码:

代码语言:javascript
复制
vectorList2Matrix<-function(vectorList){
 nzCount<-lapply(vectorList, function(x) length(x@j));
 nz<-sum(do.call(rbind,nzCount));
 r<-vector(mode="integer",length=nz);
 c<-vector(mode="integer",length=nz);
 v<-vector(mode="integer",length=nz);
 ind<-1;
 for(i in 1:length(vectorList)){
    ln<-length(vectorList[[i]]@i);
    if(ln>0){
     r[ind:(ind+ln-1)]<-i;
     c[ind:(ind+ln-1)]<-vectorList[[i]]@j+1
     v[ind:(ind+ln-1)]<-vectorList[[i]]@x
     ind<-ind+ln;
    }
 }
 return (sparseMatrix(i=r,j=c,x=v));
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8843700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档