【问题标题】:Rollapply on large sparse matrices在大型稀疏矩阵上滚动应用
【发布时间】:2019-06-14 02:25:31
【问题描述】:

有没有办法通过 rollapply/rollsum 在固定长度的窗口上计算 sparse 矩阵上的行和?为方便起见,我正在使用dgTMatrix,但我的问题并非特定于此类。例如,考虑生成一个8 x 10 稀疏矩阵。

library(Matrix)
i <- c(1,3:8); j <- c(2,9,6:10); x <- 7 * (1:7)
A <- sparseMatrix(i, j, x = x, giveCsparse = FALSE)    

> A
8 x 10 sparse Matrix of class "dgTMatrix"

[1,] . 7 . . .  .  .  .  .  .
[2,] . . . . .  .  .  .  .  .
[3,] . . . . .  .  .  . 14  .
[4,] . . . . . 21  .  .  .  .
[5,] . . . . .  . 28  .  .  .
[6,] . . . . .  .  . 35  .  .
[7,] . . . . .  .  .  . 42  .
[8,] . . . . .  .  .  .  . 49

在不首先强制转换为矩阵(例如 as.matrix())的情况下,一种天真的方法是使用 sapply 计算每个 window=2 列的行和,从而得到 8 x 5 密集强>矩阵。

window = 2
starts = seq(1,dim(A)[2],by=window)
A_rollsum <- sapply(starts, function(x) Matrix::rowSums(A[, x:(x+window-1)]))

> A_rollsum
     [,1] [,2] [,3] [,4] [,5]
[1,]    7    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0   14
[4,]    0    0   21    0    0
[5,]    0    0    0   28    0
[6,]    0    0    0   35    0
[7,]    0    0    0    0   42
[8,]    0    0    0    0   49

这对于大型稀疏矩阵效率不高。

【问题讨论】:

  • @G.Grothendieck - 有没有办法不将其强制为标准matrix
  • 矩阵与A_rollsum不同。我已编辑问题以反映 AA_rollsum 的外观。
  • 您的A_rollsum 代码不起作用,因为未使用 by.column。我已将我的 cmets 移至一个答案,并表明两种计算结果的方法是相同的。
  • 我并不是说最后两个A_rollsum 应该产生正确的矩阵。正确的输出是带有sapply 的输出,但我想使用类似rollapply 的输出。我将删除最后两个以避免混淆。
  • 好的。我用密集而稀疏的答案对其进行了修改。

标签: r sparse-matrix rolling-computation


【解决方案1】:

1) rollapply 逐列工作,显然您希望逐行进行转置,如图所示使用 rollapply 并转回:

t(rollapply(t(as.matrix(A)), 2, by = 2, sum))

给予:

     [,1] [,2] [,3] [,4] [,5]
[1,]    7    0    0    0    0
[2,]    0    0    0    0    0
[3,]    0    0    0    0   14
[4,]    0    0   21    0    0
[5,]    0    0    0   28    0
[6,]    0    0    0   35    0
[7,]    0    0    0    0   42
[8,]    0    0    0    0   49

2) 上面使用了密集矩阵,但如果你真的需要稀疏矩阵,请注意 rollapply 在这里是一个线性运算符,所以我们可以计算它的矩阵,然后使用稀疏矩阵乘法。

d <- rollapply(diag(10), 2, by = 2, sum)
A %*% t(d)

问题已更改。这是原始问题的答案。

试试r1。我们证明它等于r2

r1 <- rollapply(rowSums(A), 3, c)
r2 <- rollapply(as.matrix(A), 3, rowSums, by.column = FALSE)
identical(r1, r2)
## [1] TRUE

r1r2 相等:

> r1
     [,1] [,2] [,3]
[1,]    7    0   14
[2,]    0   14   21
[3,]   14   21   28
[4,]   21   28   35
[5,]   28   35   42
[6,]   35   42   49

【讨论】:

    猜你喜欢
    • 2015-03-01
    • 2013-06-09
    • 2021-09-22
    • 1970-01-01
    • 2012-05-29
    • 2014-07-14
    • 1970-01-01
    • 2013-11-16
    • 2017-02-17
    相关资源
    最近更新 更多