以下代码是我项目的核心,不幸的是,考虑到我的问题的维度,它现在太慢了。有没有更有效的方法来实现相同的结果?
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()
答案 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))