2017-09-15 2 views
0

は、私は本当に大きな疎行列を持っているので、私は私の問題のいくつかの高速なソリューションを必要とする:スワップ値

レッツ・Aは(単なる例)いくつかの小さな疎行列こと:

> A 
4 x 5 sparse Matrix of class "dgCMatrix" 
      A  B  C  D  E  
    [1,]  1  1  5  4  6 
    [2,]  51  2  40  1  5  
    [3,]  3  40  10  .  50 
    [4,]  .  6  3  .  30 

> dput(A) 
new("dgCMatrix" 
    , i = c(0L, 1L, 2L, 0L, 1L, 2L, 3L, 0L, 1L, 2L, 3L, 0L, 1L, 0L, 1L, 
2L, 3L) 
    , p = c(0L, 3L, 7L, 11L, 13L, 17L) 
    , Dim = 4:5 
    , Dimnames = list(NULL, c("A", "B", "C", "D", "E")) 
    , x = c(1, 51, 3, 1, 2, 40, 6, 5, 40, 10, 3, 4, 1, 6, 5, 50, 30) 
    , factors = list() 
) 

そして、私は最初の行の値==列の位置が必要です。このように:

  A  B  C  D  E  
    [1,]  1  2  3  4  5 
    [2,]  51  1  40  1  6  
    [3,]  3  40  10  .  50 
    [4,]  .  6  5  .  30 

だから私が値を交換することです。この例では、私が交換したい:

A[1,2]A[2,2]

A[1,3]A[4,3]

A[1,5]

A[2,5]をしかし、私は本当に大きな疎行列を持っているので、私は最初に見つけなければならどこA[1,i] != iと行which(A[,i] == i)を見つけてスワップします。

ROW <- A[1,] 
    for (i in 1:ncol(ROW)){ 
    if (ROW[i] != i){ 
     a <- ROW[i] 
     b <- A[which(A[,i] == i), i] 

     p <- which(A[,i] == i) 

     A[1,i] <- b 
     A[p,i] <- a 
    } 
    } 

それは動作しますが、それは本当に遅いです:

は、私はこれを試してみました。私が扱う元の行列は28182行と28182列を持っています。

私のアプローチを改善するにはどうすればよいですか?

なぜこの奇妙なことをする必要があるのか​​聞かないでください。私はそれが必要です。 hereを見て、なぜ私がそれを必要としているかを知ることもできます。

+0

コードでは、 'p'は複数の位置を含むことがあります。そのような場合、あなたは何をしますか? –

+0

@KotaMoriこれは起こり得ません。 「A」の列の値は製品IDであり、1つの製品は1つの列に1つしかなくてもよい。 –

答えて

0

「dgTMatrix」を使用すると、行列が行ID、列ID、およびセル値に対応する3つのベクトル(i, j, x)で表される方が簡単です。

これらのベクトルを直接使用してスワッピング操作を行うことができます。

library(Matrix) 
A <- new("dgCMatrix" 
    , i = c(0L, 1L, 2L, 0L, 1L, 2L, 3L, 0L, 1L, 2L, 3L, 0L, 1L, 0L, 1L, 
      2L, 3L) 
    , p = c(0L, 3L, 7L, 11L, 13L, 17L) 
    , Dim = 4:5 
    , Dimnames = list(NULL, c("A", "B", "C", "D", "E")) 
    , x = c(1, 51, 3, 1, 2, 40, 6, 5, 40, 10, 3, 4, 1, 6, 5, 50, 30) 
    , factors = list() 
) 


B <- as(A, "dgTMatrix") 

flg1 <- ([email protected] == 0) & ([email protected] != ([email protected])) # corresponds to `i` 
val1 <- [email protected][flg1] # corresponds to `a` 
col1 <- [email protected][flg1] 

flg2 <- ([email protected] %in% col1) & ([email protected] == ([email protected])) # corresponds to `p` 
val2 <- [email protected][flg2] # corresponds to `b` 

[email protected][flg1] <- val2 
[email protected][flg2] <- val1 

B