R中的高效矩阵运算

时间:2015-11-20 23:01:11

标签: r performance matrix apply finance

以下代码是我项目的核心,不幸的是,考虑到我的问题的维度,它现在太慢了。有没有更有效的方法来实现相同的结果?

nbassets <- 80
nbrisksource <- 100
nbsimul <- 300000
set.seed(100)
#generate random number for each 100 source of risk in many simulations
random <- matrix(runif(nbsimul*nbrisksource)+0.9,nrow=nbsimul,ncol=nbrisksource)
# random vulnerability to each source of risk for each of 120 assets
EL_decomp <- matrix(runif(nbassets*nbrisksource),nrow=nbassets,ncol=nbrisksource)
#initiate matrix to store asset returns
asset_ret <- matrix(NA, nrow=nbsimul,ncol=nbassets)


ptm <- proc.time()
#loop through each asset
 for (i in 1:nbassets){
  #determine if the asset has been impacted by any source of risk, if yes return is -1, otherwise 0
  asset_ret[,i] <- apply(matrix(EL_decomp[i,], nrow=nbsimul,ncol=nbrisksource,byrow=TRUE) < random,1,all)-1
}
print(proc.time() - ptm)

ptm <- proc.time()

2 个答案:

答案 0 :(得分:2)

我的速度提高了18倍,基本上没有跳过所有矩阵写作并利用了R&C的回收利用:

ServletContext

首先,删除矩阵因为n_80 <- 80 n_100 <- 100 n_300000 <- 300000 set.seed(100) mat_300000_100 <- matrix(runif(n_300000*n_100), nrow=n_300000, ncol=n_100) mat_80_100 <- matrix(runif(n_80 *n_100), nrow=n_80, ncol=n_100) mat_300000_80 <- matrix(NA, nrow=n_300000, ncol=n_80) 回收矢量。必须进行转置,因为>按行而不是按行应用矢量。并且,如果可以,请使用>等优化功能代替colSums。在此,apply可以替换为apply(v,2,'all')

colSums(v)==length_v

最后,只在循环外执行一次ptm <- proc.time() for (i in 1:n_80) mat_300000_80[,i] <- colSums(mat_80_100[i,] < t(mat_300000_100))==n_100-1 print(proc.time() - ptm) # 17s 。 (或者甚至从未在你的例子中你的值完全随机......)

transpose()

答案 1 :(得分:2)

事情可以大大改善。以下是旧代码和新代码的比较:

nbassets     <- 80
nbrisksource    <- 100
nbsimul <- 300000
set.seed(100)
random <- matrix(runif(nbsimul*nbrisksource)+0.9, nrow=nbsimul,ncol=nbrisksource)

EL_decomp     <- matrix(runif(nbassets    *nbrisksource), nrow=nbassets,     ncol=nbrisksource)
asset_ret1  <- matrix(NA, nrow=nbsimul, ncol=nbassets)
asset_ret2  <- matrix(NA, nrow=nbsimul, ncol=nbassets)

ptm <- proc.time()
for (i in 1:nbassets){
  #determine if the asset has been impacted by any source of risk, if yes return is -1, otherwise 0
  asset_ret1[,i] <- apply(matrix(EL_decomp[i,],nrow=nbsimul,ncol=nbrisksource,byrow=TRUE) < random,1,all)-1
}
print(head(asset_ret1))
print(proc.time() - ptm) #182s on my old mac

#improved version
ptm <- proc.time()
randomt <- t(random)
asset_ret2 <- apply(EL_decomp, 1, function(x) (colSums(x < randomt) == nbrisksource))- 1L
print(head(asset_ret2))
print(proc.time() - ptm) #14s
print(identical(asset_ret1,asset_ret2)) 
相关问题