5

xts オブジェクトに基づいて比率テーブルを作成しています。これは (残念ながら) 約 10^6 ループを必要とする大規模なプログラムの一部であるため、かなりのボトルネックが発生するため、高速化したいと考えています。

これは私が始めたものの例です:

library(quantmod)

test.xts <- xts(sample(seq(1,5, by=.5), 50, replace=T), as.Date(1:50))

system.time(for(i in 1:10000){

  prop.table(table(test.xts))

})

>user  system elapsed 
 19.86    0.00   18.58 

私はすでに xts をマトリックスに変更しており、その結果、速度が大幅に向上しました。xts で何かが不足している場合に備えて、もともと xts であることだけを言及します。これは、マトリックスに変換することで既に見たゲインを超えて高速化します。

test.mat <- as.matrix(test.xts)

system.time(for(i in 1:10000){

  prop.table(table(test.mat))

})

>user  system elapsed 
 2.78    0.00    2.90 

しかし、私はそれをできるだけ速くしたいと思っているので、他の人がさらに改善するための提案をしてくれることを願っています. 私が見落としている明らかなアプローチがあることを願っています。

追加情報として、これらのテーブルからの出力は、最終的に別の期間からの同様の出力とマージされるため、ディメンションの名前はそのままにしておく必要があります。(つまり、時間 1 の値「10」の割合を時間 2 の「10」の割合と一致させる必要があります)。

どんな助けでも大歓迎です。

4

2 に答える 2

5

table()高価な因子を暗黙的に作成します。あなたの場合、tabulate()すでに整数を持っているので、使用することで多く(10倍以上)節約できます:

a <- tabulate(test.mat)
names(a) <- seq_along(a)
a / sum(a)
   1    2    3    4    5    6    7    8    9   10 
0.16 0.14 0.08 0.14 0.08 0.16 0.02 0.06 0.10 0.06 

タイミング:

system.time(for(i in 1:10000){
  a <- tabulate(test.mat)
  names(a) <- seq_along(a)
  a/sum(a)
})

 user  system elapsed 
0.208   0.002   0.210 

比較のタイミング:

system.time(for(i in 1:10000) prop.table(table(test.mat)))
 user  system elapsed 
3.373   0.028   3.402 
于 2012-05-18T17:49:05.740 に答える
3

ジョランのコメントに基づいて構築するには、tabulate()直接使用するとより速く証明できます。注目に値する3つの癖があります。

  1. 整数のみを処理し、小数を切り捨てます。
  2. すべての負の値とゼロを黙って無視します。
  3. カウントがゼロであっても、すべての値 1:n のビンを作成します。

詳細?tabulateについては、を参照してください。

その注意点を踏まえて、最大 9 倍のスピードアップを実現する関数を次に示します。

prop2 <- function(x){
  x <- tabulate(x)
  out <- x/sum(x)
  names(out) <- seq_along(out)
  return(out)
}

テストスピード:

library(rbenchmark)
test.mat <- as.matrix(test.xts)
f1 <- function() prop.table(table(test.mat))
benchmark(f1(), prop2(test.mat),
           replications = 1000,
           columns = c("test", "relative", "elapsed"),
           order = "relative")
#------
             test relative elapsed
2 prop2(test.mat)      1.0    0.10
1            f1()      9.1    0.91

出力が同じであることを確認します。

> prop.table(table(test.mat))
test.mat
   1    2    3    4    5    6    7    8    9   10 
0.04 0.02 0.20 0.12 0.08 0.10 0.06 0.14 0.12 0.12 
> prop2(test.mat)
   1    2    3    4    5    6    7    8    9   10 
0.04 0.02 0.20 0.12 0.08 0.10 0.06 0.14 0.12 0.12
于 2012-05-18T17:51:34.693 に答える