如何合并大型稀疏矩阵

5
我是一名有用的助手,可以为您翻译文本。

我有一个包含25个稀疏矩阵的大列表(它们非常大-其中一个矩阵中有100M或更多元素),我需要将它们合并成一个大的稀疏矩阵。

例如:一个矩阵A可能看起来像这样(它是我真实矩阵的子矩阵,其中包含100M个元素之一):

> A
5 x 4 sparse Matrix of class "dgCMatrix"
              SKU
CustomerID         404     457     547     558     
  100002_24655       1       .       .       .       
  100003_46919       .       1       1       .       
  100007_46702       .       .       .       .       
  100012_47709       .       .       .       .       
  100013_46132       1       1       1       1 

> dput(A)
new("dgCMatrix"
    , i = c(0L, 4L, 1L, 4L, 1L, 4L, 4L)
    , p = c(0L, 2L, 4L, 6L, 7L)
    , Dim = c(5L, 4L)
    , Dimnames = structure(list(CustomerID = c("100002_24655", "100003_46919", 
"100007_46702", "100012_47709", "100013_46132"), SKU = c("404", 
"457", "547", "558")), .Names = c("CustomerID", "SKU"
))
    , x = c(1, 1, 1, 1, 1, 1, 1)
    , factors = list()
)

另一个 B 可能看起来像这样:

> B
7 x 5 sparse Matrix of class "dgCMatrix"
               SKU
CustomerID          191     404     558     715     787        
  100002_24655        .       .       .       .       .              
  100007_46702        1       1       1       1       1              
  100012_47709        .       .       1       .       .              
  100013_46132        .       .       .       .       1              
  100014_46400        .       .       .       .       .             
  100014_605414       1       1       1       .       .              
  100014_631294       .       .       1       1       1              

> dput(B)
new("dgCMatrix"
    , i = c(1L, 5L, 1L, 5L, 1L, 2L, 5L, 6L, 1L, 6L, 1L, 3L, 6L)
    , p = c(0L, 2L, 4L, 8L, 10L, 13L)
    , Dim = c(7L, 5L)
    , Dimnames = structure(list(CustomerID = c("100002_24655", "100007_46702", 
"100012_47709", "100013_46132", "100014_46400", "100014_605414", 
"100014_631294"), SKU = c("191", "404", "558", "715", 
"787")), .Names = c("CustomerID", "SKU"))
    , x = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    , factors = list()
)

输出应该如下所示:(第一部分是第一个矩阵,第二部分是第二个矩阵 - 我用空格分隔以获得更好的视图)
12 x 7 sparse Matrix of class "dgCMatrix"    
             404  457  547  558  191  715  787    
     [1, ]     1    .    .    .    .    .    .     
     [2, ]     .    1    1    .    .    .    .
     [3, ]     .    .    .    .    .    .    .
     [4, ]     .    .    .    .    .    .    .
     [5, ]     1    1    1    1    .    .    .

     [6, ]     .    .    .    .    .    .    .
     [7, ]     1    .    .    1    1    1    1
     [8, ]     .    .    .    1    .    .    .
     [9, ]     .    .    .    .    .    .    1
     [10,]     .    .    .    .    .    .    .
     [11,]     1    .    .    1    1    .    .
     [12,]     .    .    .    1    .    1    1

这意味着我想按列名合并。那么我该如何合并所有25个稀疏矩阵?


`> l <- list(A,B,C,.......)
do.call(rbind, l)`
- Sagar
3
如果您想使用rbind函数,矩阵必须具有相同的列数。 - Martina Zapletalová
@MartinaZapletalová - 我没意识到它们在列数上有所不同...我的错。 - Sagar
1
这是您要找的吗?https://dev59.com/F6Dia4cB1Zd3GeqPEHrY#43121758 - dww
1个回答

3

所以我修改了一下dww的回答,以避免我在评论中提到的错误。但是这种方法速度有点慢,因为我的矩阵实在是太大了。

> proc.time() - ptm
   user  system elapsed 
572.384 213.179 793.550

这是编辑后的代码:

merge.sparse = function(M.list) {
  A = M.list[[1]]

  for (i in 2:length(M.list)){ #i indexes of matrices
    # finding what's missing
    misA = colnames(M.list[[i]])[!colnames(M.list[[i]]) %in% colnames(A)]
    misB = colnames(A)[!colnames(A) %in% colnames(M.list[[i]])]

    misAl = as.vector(numeric(length(misA)), "list")
    names(misAl) = misA
    misBl = as.vector(numeric(length(misB)), "list")
    names(misBl) = misB

    ## adding missing columns to initial matrices
    An = Reduce(cbind, c(A, misAl))
    if (length(misA) > 0)
       {
       lenA <- ncol(An)-length(misA)+1
       colnames(An)[lenA:ncol(An)] = names(misAl)
       }

    Bn = Reduce(cbind, c(M.list[[i]], misBl))
    if(length(misB) > 0)
       {
       lenB <- ncol(Bn)-length(misB)+1
       colnames(Bn)[lenB:ncol(Bn)] = names(misBl)
       }

    Bn <- Bn[,colnames(An)]

    # final bind
    A = rbind(An, Bn, use.names = T)
    print(c(length(M.list), i))
  } 
  A
}

我编辑了答案,修复了一个小错误,当misA或misB为空时会发生。 - nico

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接