2016-07-28 9 views
1

ich eine n x p Matrix haben, die wie folgt aussieht:„Diagonalisierung“ jede Zeile einer Matrix

n = 100 
p = 10  
x <- matrix(sample(c(0,1), size = p*n, replace = TRUE), n, p) 

Ich möchte A eine n x p x p Array erstellen, deren k ten Element entlang der ersten Dimension ist eine p x p Diagonalmatrix enthält die Elemente von x[k,]. Was ist der effizienteste Weg, dies in R zu tun? Ich suche nach einem Weg, der outer (oder einen anderen vektorisierten Ansatz) anstelle einer der apply Funktionen verwendet.

Lösung lapply mit:

A <- aperm(simplify2array(lapply(1:nrow(x), function(i) diag(x[i,]))), c(3,2,1)) 

Ich bin für etwas effizienter als diese suchen.

Danke.

Antwort

2

Als Ausgangspunkt, hier ist eine bescheidene for Loop-Methode mit Vorbelegung der Matrix.

# pre-allocate matrix of desired size 
myArray <- array(0, dim=c(ncol(x), ncol(x), nrow(x))) 
# fill in array 
for(i in seq_len(nrow(x))) myArray[,,i] <- diag(x[i,]) 

Es sollte relativ schnell laufen. Auf meiner Maschine dauerte die Methode lapply für eine Matrix 1000 X 100 0,87 Sekunden, während die Schleife for (einschließlich der Vorbelegung des Arrays) 0,25 Sekunden benötigte, um die Matrix in das gewünschte Array zu transformieren. So war die for Schleife etwa 3,5 mal schneller.


Ihre ursprüngliche Matrix

Hinweis transponieren auch, dass die Zeilenoperationen auf R-Matrizen sind in der Regel langsamer als Spaltenoperationen sein. Dies liegt daran, dass Matrizen im Speicher nach Spalte gespeichert werden. Wenn Sie Ihre Matrix transponieren und die Operation auf diese Weise ausführen, sinkt die Zeit für die Operation auf 100X1000-Matrix auf 0,14, die Hälfte der ersten für die Schleife und 7-mal schneller als die lapply-Methode.