簡體   English   中英

最快的R等價於MATLAB的reshape()方法?

[英]Fastest R equivalent to MATLAB's reshape() method?

我正在將一個MATLAB腳本轉換為R並對此感到后悔,因為它現在速度較慢。 我試圖盡可能地使用“矢量化函數”,但我對R來說相對較新,並且不知道這是什么意思。 如果使用大量運算符(包括括號),我對循環的研究只比R中的apply()方法慢。 否則,我不知道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中,此代碼由稱為“reshape”的內置函數執行,如下所示:

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

我計算了當前的R代碼並且它實際上超級快,但我仍然想學習矢量化以及如何將我的代碼轉換為apply()以便於閱讀。

user  system elapsed 
0.003   0.000   0.002 

第一步是將數組w6x9轉換為3x3x6大小,在您的情況下,可以通過轉置然后更改維度來完成:

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

這幾乎是我們想要的,除了前兩個尺寸被翻轉。 你可以使用aperm函數來轉置它們:

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

這比循環遍歷矩陣並逐行復制數據要快得多。 為了看到這一點,讓我們看一個包含10,000行和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倍以上。

我沒有測試速度,但你可以試試

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.6553210

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM