2015-06-21 89 views
4

我正在将一个MATLAB脚本转换为R,并对此感到遗憾,因为此刻它速度较慢。我试图尽可能多地使用“矢量化函数”,但我对R相对比较陌生,不知道这是什么意思。如果你使用大量的运算符(包括括号),那么从我的循环研究来说,它只比R中的apply()方法慢。否则,我不会看到R可以做些什么来进一步减慢它。这是我想要加速的代码。等效于MATLAB的reshape()方法的最快R?

somPEs <- 9; 
inputPEs <- 6; 
initial_w <- matrix(1, nrow=somPEs, ncol=inputPEs) 
w <- apply(initial_w, 1, function(i) runif(i)); 
# Reshape w to a 3D matrix of dimension: c(sqrt(somPEs), sqrt(somPEs), inputPEs) 
nw <- array(0, dim=c(sqrt(somPEs), sqrt(somPEs), inputPEs)) 
for (i in 1:inputPEs) { 
    nw[,,i] <- matrix(w[i,], nrow=sqrt(somPEs), ncol=sqrt(somPEs), byrow=TRUE) 
} 
w <- nw; 

在MATLAB中,该代码是由被称为“重塑”一个内置的功能执行,如按以下步骤进行:

w = reshape(w,[sqrt(somPEs) sqrt(somPEs) inputPEs]); 

我计时我的当前R代码,它实际上是超快速,但我仍然想了解矢量化以及如何将我的代码转换为apply()以提高可读性。

user system elapsed 
0.003 0.000 0.002 

回答

5

的第一步是你的阵列w6x9转换为3x3x6大小,而你的情况可以通过调换,然后改变尺寸来完成:

neww <- t(w) 
dim(neww) <- c(sqrt(somPEs), sqrt(somPEs), inputPEs) 

这是我们想要的几乎什么除了前两个维度被翻转之外。您可以使用aperm功能移调他们:

neww <- aperm(neww, c(2, 1, 3)) 

这应该是一个很好的处理速度比通过矩阵循环和排单独复制了数据。看到这一点,让我们来看看一个更大的示例10000行和100列(将映射到10x10x10k矩阵):

josilber <- function(w) { 
    neww <- t(w) 
    dim(neww) <- c(sqrt(dim(w)[2]), sqrt(dim(w)[2]), dim(w)[1]) 
    aperm(neww, c(2, 1, 3)) 
} 
OP <- function(w) { 
    nw <- array(0, dim=c(sqrt(dim(w)[2]), sqrt(dim(w)[2]), dim(w)[1])) 
    for (i in 1:(dim(w)[1])) { 
    nw[,,i] <- matrix(w[i,], nrow=sqrt(dim(w)[2]), ncol=sqrt(dim(w)[2]), byrow=TRUE) 
    } 
    nw 
} 
bigw <- matrix(runif(1000000), nrow=10000, ncol=100) 
all.equal(josilber(bigw), OP(bigw)) 
# [1] TRUE 
microbenchmark(josilber(bigw), OP(bigw)) 
# Unit: milliseconds 
#   expr  min  lq  mean  median  uq  max neval 
# josilber(bigw) 8.483245 9.08430 14.46876 9.431534 11.76744 135.7204 100 
#  OP(bigw) 83.379053 97.07395 133.86606 117.223236 129.28317 1553.4381 100 

使用tdimaperm的方法是10倍以上,快于中位数运行时比循环方法。

2

我没有测试的速度,但你可以尝试

nw1 <- aperm(`dim<-`(t(w), list(3, 3, 6)), c(2, 1, 3)) 

> nw1 
, , 1 

      [,1]  [,2]  [,3] 
[1,] 0.8257185 0.5475478 0.4157915 
[2,] 0.8436991 0.3310513 0.1546463 
[3,] 0.1794918 0.1836032 0.2675192 

, , 2 

      [,1]  [,2]  [,3] 
[1,] 0.6914582 0.1674163 0.2921129 
[2,] 0.2558240 0.4269716 0.7335542 
[3,] 0.6416367 0.8771934 0.

, , 3 

      [,1]  [,2]  [,3] 
[1,] 0.9761232 0.05223183 0.6651574 
[2,] 0.5740032 0.80621864 0.2295017 
[3,] 0.1138926 0.76009870 0.6932736 

, , 4 

      [,1]  [,2]  [,3] 
[1,] 0.437871558 0.5172516 0.1145181 
[2,] 0.006923583 0.3235762 0.3751655 
[3,] 0.823235642 0.4586850 0.6013853 

, , 5 

      [,1]  [,2]  [,3] 
[1,] 0.7425735 0.1665975 0.8659373 
[2,] 0.1418979 0.1878132 0.2357267 
[3,] 0.6963537 0.5391961 0.1112467 

, , 6 

      [,1]  [,2]  [,3] 
[1,] 0.7246276 0.02896792 0.04692648 
[2,] 0.7563403 0.22027518 0.41138672 
[3,] 0.8303413 0.31908307 0.25180560