我有一个类似
的矩阵A= [ 1 2 4
2 3 1
3 1 2 ]
我想按行和按列计算累积总和,也就是说,我希望结果是
B = [ 1 3 7
3 8 13
6 12 19 ]
有关如何快速在R中制作此内容的任何想法? (可能使用函数cumsum) (我有巨大的矩阵)
谢谢!
答案 0 :(得分:16)
单行:
t(apply(apply(A, 2, cumsum)), 1, cumsum))
根本的观察结果是,您可以先计算列上的累积总和,然后计算此矩阵对行的累积总和。
注意:在执行行时,必须转置结果矩阵。
你的例子:
> apply(A, 2, cumsum)
[,1] [,2] [,3]
[1,] 1 2 4
[2,] 3 5 5
[3,] 6 6 7
> t(apply(apply(A, 2, cumsum), 1, cumsum))
[,1] [,2] [,3]
[1,] 1 3 7
[2,] 3 8 13
[3,] 6 12 19
关于绩效:我现在已经知道这种方法对大矩阵有多好。复杂性方面,这应该接近最优。通常情况下,apply
的性能也不差。
现在我好奇 - 哪种方法更好?一个简短的基准:
> A <- matrix(runif(1000*1000, 1, 500), 1000)
>
> system.time(
+ B <- t(apply(apply(A, 2, cumsum), 1, cumsum))
+ )
User System elapsed
0.082 0.011 0.093
>
> system.time(
+ C <- lower.tri(diag(nrow(A)), diag = TRUE) %*% A %*% upper.tri(diag(ncol(A)), diag = TRUE)
+ )
User System elapsed
1.519 0.016 1.530
因此:应用优于矩阵乘法15倍。(仅用于比较:MATLAB需要0.10719秒。)结果并不令人惊讶,因为apply
- 版本可以在O中完成(n ^ 2),矩阵乘法需要约。 O(n ^ 2.7)计算。因此,如果n足够大,那么矩阵乘法提供的所有优化都应该丢失。
答案 1 :(得分:4)
使用matrixStats包和更大的示例矩阵,这是一个更有效的实现:
library(matrixStats)
A <- matrix(runif(10000*10000, 1, 500), 10000)
# Thilo's answer
system.time(B <- t(apply(apply(A, 2, cumsum), 1, cumsum)))
user system elapsed
3.684 0.504 4.201
# using matrixStats
system.time(C <- colCumsums(rowCumsums(A)))
user system elapsed
0.164 0.068 0.233
all.equal(B, C)
[1] TRUE
答案 2 :(得分:0)
我的解决方案:函数 cumsum_row()(见下文)采用矩阵 M 并返回 M 行的累积总和矩阵。函数 cumsum_col() 对列执行相同的操作。
cumsum_row <- function(M) {
M2 <- c()
for (i in 1:nrow(M))
M2 <- rbind(M2, cumsum(M[i,]))
return (M2)
}
cumsum_col <- function(M) {
return (t(cumsum_row(t(M))))
}
示例:
> M <- matrix(rep(1, 9), nrow=3)
> M
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 1 1
[3,] 1 1 1
> cumsum_row(M)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 2 3
[3,] 1 2 3