【问题标题】:R convert matrix or data frame to sparseMatrixR将矩阵或数据框转换为sparseMatrix
【发布时间】:2012-05-20 06:39:39
【问题描述】:

我有一个常规矩阵(非稀疏),我想将其转换为sparseMatrix(使用Matrix 包)。有没有一个函数可以做到这一点,还是我需要做一堆循环?

例如。

> regMat <- matrix(0, nrow=10, ncol=10)
> regMat[3,5] <- round(runif(1),2)*100
> regMat[2,8] <- round(runif(1),2)*100
> regMat[8,4] <- round(runif(1),2)*100
> regMat[1,6] <- round(runif(1),2)*100
> regMat[7,4] <- round(runif(1),2)*100
> regMat 
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    0    0    0    0   49    0    0    0     0
 [2,]    0    0    0    0    0    0    0   93    0     0
 [3,]    0    0    0    0   20    0    0    0    0     0
 [4,]    0    0    0    0    0    0    0    0    0     0
 [5,]    0    0    0    0    0    0    0    0    0     0
 [6,]    0    0    0    0    0    0    0    0    0     0
 [7,]    0    0    0    8    0    0    0    0    0     0
 [8,]    0    0    0   14    0    0    0    0    0     0
 [9,]    0    0    0    0    0    0    0    0    0     0
[10,]    0    0    0    0    0    0    0    0    0     0

有什么建议吗?

【问题讨论】:

  • 制作样本数据的小建议:regMat[cbind(c(3,2,8,1,7),c(5,8,4,6,4))] &lt;- round(runif(5,0,100))

标签: r matrix sparse-matrix


【解决方案1】:

这里有两个选项:

library(Matrix)

A <- as(regMat, "sparseMatrix")       # see also `vignette("Intro2Matrix")`
B <- Matrix(regMat, sparse = TRUE)    # Thanks to Aaron for pointing this out

identical(A, B)
# [1] TRUE
A
# 10 x 10 sparse Matrix of class "dgCMatrix"
#                              
#  [1,] . . .  .  . 45 .  . . .
#  [2,] . . .  .  .  . . 59 . .
#  [3,] . . .  . 95  . .  . . .
#  [4,] . . .  .  .  . .  . . .
#  [5,] . . .  .  .  . .  . . .
#  [6,] . . .  .  .  . .  . . .
#  [7,] . . . 23  .  . .  . . .
#  [8,] . . . 63  .  . .  . . .
#  [9,] . . .  .  .  . .  . . .
# [10,] . . .  .  .  . .  . . .

【讨论】:

  • 还有Matrix(regMat, sparse=TRUE)
  • 谢谢@Aaron。我不知道那个成语,但已将其作为第二个选项添加到答案中。
  • @JoshO'Brien 你知道是否有直接从文件转换的选项吗?因为密集矩阵可能太大而无法完全读入内存。谢谢!
  • 作为我问题的部分答案:There are faster ways to read a file.
【解决方案2】:

乔希的回答很好,但这里有更多选择和解释。

Nit Picky “我有一个常规矩阵(非稀疏)...”实际上你 确实 有一个稀疏矩阵(大多数为 0 的矩阵);它只是未压缩的格式。您的目标是将其置于压缩存储格式中。

稀疏矩阵可以压缩成多种存储格式。 Compressed Sparse Column (CSC)Compressed Sparse Row (CSR) 是两种主要格式。 as(regMat, "sparseMatrix") 将您的矩阵转换为 dgCMatrix 类型,这是压缩的稀疏列。这通常是您想要的,但我更愿意明确说明。

library(Matrix)

matCSC <- as(regMat, "dgCMatrix")  # compressed sparse column CSC
matCSC
10 x 10 sparse Matrix of class "dgCMatrix"

 [1,] . . .  .  . 57 .  . . .
 [2,] . . .  .  .  . . 27 . .
 [3,] . . .  . 90  . .  . . .
 [4,] . . .  .  .  . .  . . .
 [5,] . . .  .  .  . .  . . .
 [6,] . . .  .  .  . .  . . .
 [7,] . . . 91  .  . .  . . .
 [8,] . . . 37  .  . .  . . .
 [9,] . . .  .  .  . .  . . .
[10,] . . .  .  .  . .  . . .

matCSR <- as(regMat, "dgRMatrix")  # compressed sparse row CSR
matCSR
10 x 10 sparse Matrix of class "dgRMatrix"

 [1,] . . .  .  . 57 .  . . .
 [2,] . . .  .  .  . . 27 . .
 [3,] . . .  . 90  . .  . . .
 [4,] . . .  .  .  . .  . . .
 [5,] . . .  .  .  . .  . . .
 [6,] . . .  .  .  . .  . . .
 [7,] . . . 91  .  . .  . . .
 [8,] . . . 37  .  . .  . . .
 [9,] . . .  .  .  . .  . . .
[10,] . . .  .  .  . .  . . .

虽然它们在表面上看起来和行为相同,但在内部它们存储数据的方式不同。 CSC 检索数据列的速度更快,而 CSR 检索行的速度更快。它们还占用不同数量的空间,具体取决于您的数据结构。

此外,在此示例中,您要将未压缩的稀疏矩阵转换为压缩矩阵。通常您这样做是为了节省内存,因此构建一个未压缩的矩阵只是为了将其转换为压缩形式就无法达到目的。在实践中,从(行、列、值)三元组的表中构造压缩稀疏矩阵更为常见。您可以使用 Matrix 的 sparseMatrix() 函数来做到这一点。

# Make data.frame of (row, column, value) triplets
df <- data.frame(
  rowIdx = c(3,2,8,1,7),
  colIdx = c(5,8,4,6,4),
  val = round(runif(n = 5), 2) * 100
)

df
  rowIdx colIdx val
1      3      5  90
2      2      8  27
3      8      4  37
4      1      6  57
5      7      4  91

# Build CSC matrix
matSparse <- sparseMatrix(
  i = df$rowIdx,
  j = df$colIdx, 
  x = df$val, 
  dims = c(10, 10)
)

matSparse
10 x 10 sparse Matrix of class "dgCMatrix"

 [1,] . . .  .  . 57 .  . . .
 [2,] . . .  .  .  . . 27 . .
 [3,] . . .  . 90  . .  . . .
 [4,] . . .  .  .  . .  . . .
 [5,] . . .  .  .  . .  . . .
 [6,] . . .  .  .  . .  . . .
 [7,] . . . 91  .  . .  . . .
 [8,] . . . 37  .  . .  . . .
 [9,] . . .  .  .  . .  . . .
[10,] . . .  .  .  . .  . . .

无耻的插头 - 我有 blog article covering this stuff 和更多,如果你有兴趣的话。

【讨论】:

    【解决方案3】:

    对于矩阵,已经有人有答案了。

    对于 data.table,有一个包完成了这项工作。

    library(Matrix)
    library(mltools)
    x = data.table()
    sparseM <- sparsify(x) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-16
      • 1970-01-01
      相关资源
      最近更新 更多