2017-09-15 3 views
0

ich eine wirklich große Sparse Matrix haben, so brauche ich einige schnelle Lösung meines Problems:Swapping Werte in großen Sparse Matrix

Lassen Sie uns A einige kleine Sparse Matrix sein (nur zum Beispiel):

> 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() 
) 

Und ich brauche die ersten Zeilenwerte == Spaltenposition. Gefällt mir:

  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 

Also alles, was ich will ist, die Werte zu tauschen. In diesem Beispiel möchte ich tauschen zu:

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

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

A[1,5] und A[2,5]

Aber ich habe wirklich große Sparse Matrix, also muss ich zuerst finden, wo A[1,i] != i und dann finden Sie die Zeile which(A[,i] == i) und tauschen Sie sie aus.

Ich versuchte dies:

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 
    } 
    } 

Es funktioniert, aber es ist wirklich langsam. Die ursprüngliche Matrix, mit der ich arbeite, hat 28182 Zeilen und 28182 Spalten.

Wie kann ich meinen Ansatz verbessern?

Bitte frag mich nicht, warum ich dieses merkwürdige Ding machen muss. Ich brauche es nur. Sie können auch sehen here und finden Sie heraus, warum ich es brauche.

+0

In Ihrem Code kann 'p' mehr als eine Position enthalten. Was würden Sie in solchen Fällen tun? –

+0

@KotaMori das kann nicht passieren. Die Werte in den Spalten von "A" sind Produkt-IDs und ein Produkt kann nur einmal in einer Spalte sein. –

Antwort

0

Es wäre einfacher, wenn Sie mit "dgTMatrix" arbeiten, wobei eine Matrix durch drei Vektoren dargestellt wird, (i, j, x), die den Zeilen-IDs, Spalten und Zellenwerten entspricht.

Ihr Auslagerungsvorgang kann unter Verwendung dieser Vektoren direkt ausgeführt werden.

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