15

私は次のようなマトリックスを持っています

A= [ 1 2 4
     2 3 1
     3 1 2 ]

行ごとと列ごとの累積合計を計算したいのですが、結果は次のようになります。

B = [ 1  3  7 
      3  8  13 
      6  12 19 ]

これをRですばやく作成する方法についてのアイデアはありますか?(おそらく関数cumsumを使用しています)(私は巨大な行列を持っています)

ありがとう!

4

3 に答える 3

17

ワンライナー:

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秒が必要です)。-versionapplyはO(n ^ 2)で実行できますが、行列の乗算は約が必要です。O(n ^ 2.7)の計算。したがって、nが十分に大きい場合、行列乗算が提供するすべての最適化は失われるはずです。

于 2012-11-22T20:50:15.880 に答える
6

これは、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
于 2016-06-22T15:54:32.930 に答える
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
  
于 2021-03-24T13:04:46.867 に答える