在写入时从矩阵/副本中提取补丁

时间:2013-01-08 13:26:15

标签: r

我有一个相当大的(1040x1392)双打矩阵,我想提取另一个矩阵,其列是第一个矩阵的16x16补丁。 (我知道,这是一个很多数据,使用它可能不实际,但这应该有用......)

我尝试使用此代码,其中'data'是原始矩阵:

# Create a matrix of starting coordinates for each patch
patch.size = 16
patch.inc = patch.size - 1
coords = expand.grid(x=1:(ncol(data)-patch.inc), y=1:(nrow(data)-patch.inc))
coords = as.matrix(coords)

# Pre-allocate the destination matrix
patches = double(nrow(coords)*patch.size^2)
dim(patches) = c(patch.size^2, nrow(coords))

#Create overlapping patches
for (i in 1:nrow(coords))
{
  x=coords[i,1]
  y=coords[i,2]
  patches[,i] = as.vector(data[y:(y+patch.inc), x:(x+patch.inc)])
}

在一台速度相当快的Win7-64机器上运行8GB内存时运行速度慢得多;即使只创建100个补丁也很慢。

事实证明,补丁[,i]的分配是问题所在。看一下任务管理器,当我分配补丁[,i]时,内存使用量会出现大幅增长。

我有几个问题。首先,发生了什么?看起来整个补丁矩阵正在每个作业中被复制。是对的吗?如果是这样,为什么?我认为预先分配补丁矩阵可以避免这种情况。第二,有没有更好的方法来编写这段代码,以便它可以在我的生命周期内完成:-)?

谢谢!肯特

1 个答案:

答案 0 :(得分:1)

对于第二个问题,这是使用lapply的解决方案。

如果您希望将确切的输出作为脚本,则可以转置结果out。我检查了较小的尺寸,并确认其等于您的输出patches

set.seed(1234)
nr <- 1040
nc <- 1392
data <- matrix(rnorm(nr*nc), nrow = nr)
patch.size <- 16
idx <- expand.grid(1:(ncol(data)-patch.size+1), 1:(nrow(data)-patch.size+1))
idx[,3] <- idx[,1]+patch.size-1
idx[,4] <- idx[,2]+patch.size-1
idx <- as.matrix(idx)

# using rbenchmark
require(rbenchmark)
myFun <- function() {
    out <- do.call(rbind, lapply(1:nrow(idx), 
        function(tx) c(data[idx[tx,2]:idx[tx,4], idx[tx,1]:idx[tx,3]])))
}
benchmark(myFun(), replications = 2)

# Result:
     test replications elapsed relative user.self sys.self user.child sys.child
1 myFun()            2 152.146        1   147.957    4.184          0         0

# using system.time
system.time(out <- do.call(rbind, lapply(1:nrow(idx), 
        function(tx) c(data[idx[tx,2]:idx[tx,4], idx[tx,1]:idx[tx,3]]))))        

# Result
  user  system elapsed 
58.852   1.784  60.638