3

整数のみが入力された100x100の行列で、要素1,1で始まる(および含む)各行内でペアワイズ比較を実行しています。TRUEの比較では、別の事前に割り当てられた行列[x]の対応する要素で+1を集計します(これは単なる類似性行列です)。

ネストされたforループを使用する場合、この操作では、行ごとにN *(N-1)/ 2+Nの比較が必要です。私のマシンでは、以下のコードはそれほど時間はかかりませんが、これを行うためのより良い(より速く、よりエレガントな)方法はありますか?「適用」を使ったベクトル計算を考えましたが、今のところ喜びはありません。

result <- matrix( round(rnorm(10000,sample(5))), ncol=100)
x <-matrix(data=0, nrow=100,ncol=100)

system.time(
for (i in 1:100) {
  for (j in 1:100) {
    for (k in j:100) {
        if (result[i,][j] == result[i,][k]) {
        x[j,][k] = x[j,][k] + 1
        }
    }
  }
}
)
user  system elapsed
6.586   0.599   7.192

これが小さな例です:

「結果」マトリックス

      [,1] [,2] [,3] [,4]
[1,]    1    6    1    1
[2,]    6    1    5    3
[3,]    1    5    4    4
[4,]    2    3    4    2

structure(c(1, 6, 1, 2, 6, 1, 5, 3, 1, 5, 4, 4, 1, 3, 4, 2), .Dim = c(4L,4L))

コードを適用した後、x行列で次のことを期待します。

      [,1] [,2] [,3] [,4]
[1,]    4    0    1    2
[2,]    0    4    0    0
[3,]    0    0    4    2
[4,]    0    0    0    4
4

1 に答える 1

5

これは、100 行 100 列のresult行列を使用した私のマシンでは約 100 倍高速 (50 ミリ秒) です。

for (i in 1:ncol(result))
   for (j in i:ncol(result))
      x[i, j] <- sum(result[, i] == result[, j])

これは約 200 倍高速ですが、理解するのが少し難しいかもしれません。

x <- apply(result, 2, function(y)colSums(result == y))
x[lower.tri(x)] <- 0

それでもまだ十分に速くない場合は、この正確な機能が多くの距離パッケージのいずれかにまだ実装されていないかどうかを調べるか、Rcpp実装を試してみます. 私の提案ではすでにかなりの量のベクトル化が使用されているため、これ以上の効果が得られるかどうかはわかりません。

于 2012-11-25T13:26:45.193 に答える