矢量化R-loop以获得更好的性能

时间:2015-07-13 09:20:23

标签: r loops vectorization

我在找到R中特定循环的矢量化表示时遇到问题。我的目标是增强循环的性能,因为它必须在算法中运行数千次。

我想在矢量' Level'定义的特定数组部分中找到最低值的位置。对于每一行。

示例:

Level = c(2,3)

让数组X的第一行为:c(2, -1, 3, 0.5, 4)

在行的1:Level[1]范围内搜索最低值的位置(即(2, -1)),得到2,因为-1< 2和-1代表该行的第二个位置。然后,搜索第二范围(Level[1]+1):(Level[1]+Level[2])中的最低值的位置(即(3, 0.5, 4)),得到4,因为0.5< 3< 4和0.5代表该行的第四个位置。

我必须在数组中的每一行执行此操作。

我对此问题的解决方法如下:

Level = c(2,3,3)  #elements per section, here: 3 sections with 2,3 and 3 levels
rows = 10  #number of rows in array X
X = matrix(runif(rows*sum(Level),-5,5),rows,sum(Level))  #array with 10 rows and sum(Level) columns, here: 8
Position_min = matrix(0,rows,length(Level))  #array in which the position of minimum values for each section and row are stored
for(i in 1:rows){
 for(j in 1:length(Level)){            #length(Level) is number of intervals, here: 3
  if(j == 1){coeff=0}else{coeff=1}
  Position_min[i,j] = coeff*sum(Level[1:(j-1)]) + which(X[i,(coeff*sum(Level[1:(j-1)])+1):sum(Level[1:j])] == min(X[i,(coeff*sum(Level[1:(j-1)])+1):sum(Level[1:j])]))
  }
}

它工作正常,但我更喜欢性能更好的解决方案。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

这将删除循环的外层:

Level1=c(0,cumsum(Level))
for(j in 1:(length(Level1)-1)){
    Position_min[,j]=max.col(-X[,(Level1[j]+1):Level1[j+1]])+(Level1[j])
}

答案 1 :(得分:3)

这是一个没有显式循环的“完全矢量化”解决方案:

findmins <- function(x, level) {
    series <- rep(1:length(Level), Level)
    x <- split(x, factor(series))
    minsSplit <- as.numeric(sapply(x, which.min))
    minsSplit + c(0, cumsum(level[-length(level)]))
}

Position_min_vectorized <- t(apply(X, 1, findmins, Level))
identical(Position_min, Position_min_vectorized)
## [1] TRUE

您可以将矩阵放入列表,然后使用parallel的{​​{1}}来获得更好的效果:

mclapply()