使嵌套的foreach循环在R中更有效?
我已经编写了一个具有3个嵌套foreach循环的函数,并行运行。该函数的目标是将30[10,5]个矩阵(即使嵌套的foreach循环在R中更有效?,r,matrix,foreach,parallel-processing,dataframe,R,Matrix,Foreach,Parallel Processing,Dataframe,我已经编写了一个具有3个嵌套foreach循环的函数,并行运行。该函数的目标是将30[10,5]个矩阵(即[[30]][10,5])的列表拆分为5[10,30]个矩阵(即[[5]][10,30])的列表 但是,我尝试使用1000000条路径运行此函数(即,foreach(m=1:1000000)),显然,性能非常糟糕 如果可能的话,我希望避免应用函数,因为我发现它们在与并行foreach循环结合使用时不能很好地工作: library(foreach) library(doParallel) #
[[30]][10,5]
)的列表拆分为5[10,30]个矩阵(即[[5]][10,30]
)的列表
但是,我尝试使用1000000条路径运行此函数(即,foreach(m=1:1000000)
),显然,性能非常糟糕
如果可能的话,我希望避免应用函数,因为我发现它们在与并行foreach循环结合使用时不能很好地工作:
library(foreach)
library(doParallel)
# input matr: a list of 30 [10,5] matrices
matrix_splitter <- function(matr) {
time_horizon <- 30
paths <- 10
asset <- 5
security_paths <- foreach(i = 1:asset, .combine = rbind, .packages = "doParallel", .export = "daily") %dopar% {
foreach(m = 1:paths, .combine = rbind, .packages = "doParallel", .export = "daily") %dopar% {
foreach(p = daily, .combine = c) %dopar% {
p[m,i]
}
}
}
df_securities <- as.data.frame(security_paths)
split(df_securities, sample(rep(1:paths), asset))
}
对于这种格式(显然是V30):
我相信你正在寻找答案:
您只需使用
do.call(rbind,matlist)
作为这些函数的输入。由于alply
的缘故,包plyr
就是为这个问题而设计的。其思想是:取消列表,以适当的方式在数组中对其进行排序,然后使用alply
将此数组转换为矩阵列表
将2
矩阵3x5
列表转换为5
矩阵2x3
列表的示例:
library(plyr)
lst = list(matrix(1:15, ncol=5), matrix(10:24, ncol=5))
alply(array(unlist(lst), c(2,3,5)),3)
#$`1`
# [,1] [,2] [,3]
#[1,] 1 3 5
#[2,] 2 4 6
#$`2`
# [,1] [,2] [,3]
#[1,] 7 9 11
#[2,] 8 10 12
#$`3`
# [,1] [,2] [,3]
#[1,] 13 15 11
#[2,] 14 10 12
#$`4`
# [,1] [,2] [,3]
#[1,] 13 15 17
#[2,] 14 16 18
#$`5`
# [,1] [,2] [,3]
#[1,] 19 21 23
#[2,] 20 22 24
我会把你所有的列表转换成一个巨大的向量,然后重新给它定尺寸 对于我的解决方案,我从以下几点开始:
[[28]]
[,1] [,2] [,3] [,4] [,5]
[1,] 1 11 21 31 41
[2,] 2 12 22 32 42
[3,] 3 13 23 33 43
[4,] 4 14 24 34 44
[5,] 5 15 25 35 45
[6,] 6 16 26 36 46
[7,] 7 17 27 37 47
[8,] 8 18 28 38 48
[9,] 9 19 29 39 49
[10,] 10 20 30 40 50
重复了三十次。这是变量orig
。我的代码:
flattened.vec <- unlist(orig) #flatten the list of matrices into one big vector
dim(flattened.vec) <-c(10,150) #need to rearrange the vector so the re-shape comes out right
transposed.matrix <- t(flattened.vec) #transposing to make sure right elements go to the right place
new.matrix.list <- split(transposed.matrix,cut(seq_along(transposed.matrix)%%5, 10, labels = FALSE)) #split the big, transposed matrix into 5 10x30 matrices
顺便说一句,这可能是
plyr
软件包本身已经做过的事情(由博维尔上校发布),只是手动操作,而不是使用外部库如何重新排列?在您的示例中,输出中没有显示输出的数字。它实际上只是从[[30]][10,5]
到[[5]]][10,30]
我觉得这些都没有很清楚的解释,但我怀疑您可能会觉得包(和函数)有帮助,然后是函数aperm
。它的性能是否受到并行开销的影响?你基本上什么都不做,把它称为并行。除此之外,据我所知,您是否想将[[30]][1000000,5]
更改为[[5]][1000000,30]
?谢谢。这对于小规模的事情来说是很好的。但是,当我得到5000000条路径时,unlist创建的向量太大(5.6GB)。没有unlist()
,有什么方法可以做到这一点吗?谢谢。这对于小规模的事情来说是很好的。但是,当我得到5000000条路径时,unlist创建的向量太大(5.6GB)。没有unlist()
,有没有办法做到这一点?数据是否必须作为列表输入?从我的测试来看,unlist()
确实很慢(设置use.names=FALSE
有点帮助,但没有多大帮助)。然而,如果你可以从一个三维向量开始,效率就会下降(数据集所需的存储空间将减少约10%)
[[28]]
[,1] [,2] [,3] [,4] [,5]
[1,] 1 11 21 31 41
[2,] 2 12 22 32 42
[3,] 3 13 23 33 43
[4,] 4 14 24 34 44
[5,] 5 15 25 35 45
[6,] 6 16 26 36 46
[7,] 7 17 27 37 47
[8,] 8 18 28 38 48
[9,] 9 19 29 39 49
[10,] 10 20 30 40 50
flattened.vec <- unlist(orig) #flatten the list of matrices into one big vector
dim(flattened.vec) <-c(10,150) #need to rearrange the vector so the re-shape comes out right
transposed.matrix <- t(flattened.vec) #transposing to make sure right elements go to the right place
new.matrix.list <- split(transposed.matrix,cut(seq_along(transposed.matrix)%%5, 10, labels = FALSE)) #split the big, transposed matrix into 5 10x30 matrices
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17]
[1,] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[2,] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[3,] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
[4,] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
[5,] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
[6,] 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
[7,] 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
[8,] 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
[9,] 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9
[10,] 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
[,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26] [,27] [,28] [,29] [,30]
[1,] 1 1 1 1 1 1 1 1 1 1 1 1 1
[2,] 2 2 2 2 2 2 2 2 2 2 2 2 2
[3,] 3 3 3 3 3 3 3 3 3 3 3 3 3
[4,] 4 4 4 4 4 4 4 4 4 4 4 4 4
[5,] 5 5 5 5 5 5 5 5 5 5 5 5 5
[6,] 6 6 6 6 6 6 6 6 6 6 6 6 6
[7,] 7 7 7 7 7 7 7 7 7 7 7 7 7
[8,] 8 8 8 8 8 8 8 8 8 8 8 8 8
[9,] 9 9 9 9 9 9 9 9 9 9 9 9 9
[10,] 10 10 10 10 10 10 10 10 10 10 10 10 10