"Diagonalize" each row of a matrix

时间:2016-07-28 20:18:38

标签: arrays r matrix vectorization

I have an n x p matrix that looks like this:

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

I want to create an n x p x p array A whose kth item along the 1st dimension is a p x p diagonal matrix containing the elements of x[k,]. What is the most efficient way to do this in R? I'm looking for a way that uses outer (or some other vectorized approach) rather than one of the apply functions.

Solution using lapply:

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

I'm looking for something more efficient than this.

Thanks.

1 个答案:

答案 0 :(得分:2)

作为一个起点,这里是一个简单的V1 V2 abc 54 => where abc is the sum of previous abc and 12bc 87gd 3 987 50 循环方法,预先分配矩阵。

for

它应该运行得相对较快。在我的机器上,对于1000 X 100矩阵,# 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,]) 方法花费0.87秒,而lapply循环(包括数组预分配)花费0.25秒将矩阵转换为您想要的数组。因此for循环的速度提高了约3.5倍。

转置原始矩阵

另请注意,R矩阵上的行操作往往比列操作慢。这是因为矩阵按列存储在内存中。如果转置矩阵并以这种方式执行操作,则在100X1000矩阵上完成操作的时间将降至0.14,即第一个for循环的一半,并且比for方法快7倍。