R并行计算中如何使用Reduce()函数?
How to use Reduce() function in R parallel computing?
我想运行一个Reduce
代码到out1
一个包含66000个列表元素的列表:
trialStep1_done <- Reduce(rbind, out1)
不过,运行用的时间太长了。我想知道我是否可以在并行计算包的帮助下 运行 这段代码。
我知道有mclapply
、mcMap
,但是我在并行计算包中没有看到像mcReduce
这样的函数。
是否有类似 mcReduce
的函数可用于在 R 中并行执行 Reduce
以完成我想完成的任务?
非常感谢@BrodieG 和@zheYuan Li,你们的回答很有帮助。我认为以下代码示例可以更准确地表示我的问题:
df1 <- data.frame(a=letters, b=LETTERS, c=1:26 %>% as.character())
set.seed(123)
df2 <- data.frame(a=letters %>% sample(), b=LETTERS %>% sample(), c=1:26 %>% sample() %>% as.character())
set.seed(1234)
df3 <- data.frame(a=letters %>% sample(), b=LETTERS %>% sample(), c=1:26 %>% sample() %>% as.character())
out1 <- list(df1, df2, df3)
# I don't know how to rbind() the list elements only using matrix()
# I have to use lapply() and Reduce() or do.call()
out2 <- lapply(out1, function(x) matrix(unlist(x), ncol = length(x), byrow = F))
Reduce(rbind, out2)
do.call(rbind, out2)
# One thing is sure is that `do.call()` is super faster than `Reduce()`, @BordieG's answer helps me understood why.
所以,至此,对于我的200000行数据集,do.call()
很好的解决了问题。
最后,我想知道这是不是更快的方法?或者@ZheYuanLi 用 matrix()
演示的方式可以在这里实现吗?
- 它很慢,因为你反复调用
rbind
。每次调用时,随着对象维度的增加,必须进行新的内存分配。
- 您的工作受内存限制,您不会从并行性中获益。在多核机器上,并行处理仅对 CPU 绑定任务有用。
如果我没有误会你的意思,你应该使用这个:
trialStep1_done <- matrix(unlist(out1), nrow = length(out1), byrow = TRUE)
示例:
out1 <- list(1:4, 11:14, 21:24, 31:34)
#> str(out1)
#List of 4
# $ : int [1:4] 1 2 3 4
# $ : int [1:4] 11 12 13 14
# $ : int [1:4] 21 22 23 24
# $ : int [1:4] 31 32 33 34
trialStep1_done <- matrix(unlist(out1), nrow = length(out1), byrow = TRUE)
#> trialStep1_done
# [,1] [,2] [,3] [,4]
#[1,] 1 2 3 4
#[2,] 11 12 13 14
#[3,] 21 22 23 24
#[4,] 31 32 33 34
感谢@BrodieG 出色的解释和基准测试结果!
我也在我的笔记本电脑上尝试了基准测试,使用与@BrodieG 完全相同的代码,这就是我得到的:
Unit: microseconds
expr min lq mean
a <- do.call(rbind, out1) 653.60 670.36 900.120
b <- matrix(unlist(out1), ncol = 20, byrow = TRUE) 170.16 177.60 224.036
c <- Reduce(rbind, out1) 65589.48 67519.32 72317.812
median uq max neval
745.54 832.36 2352.28 10
183.98 286.84 385.96 10
68897.36 69372.88 108135.96 10
问题不是rbind
,问题是Reduce
。不幸的是,R 中的函数调用非常昂贵,尤其是当您不断创建新对象时。在这种情况下,您调用 rbind
65999 次,每次调用都会创建一个新的 R 对象并添加一行。相反,您可以使用 66000 个参数调用 rbind
一次,这会快得多,因为在内部 rbind
将在 C 中进行绑定,而不必调用 R 函数 66000 次并只分配一次内存。在这里,我们将您的 Reduce
使用与哲源的 matrix/unlist 进行比较,最后将 rbind
使用 do.call
调用一次(do.call
允许您调用一个函数,所有参数指定为列表):
out1 <- replicate(1000, 1:20, simplify=FALSE) # use 1000 elements for illustrative purposes
library(microbenchmark)
microbenchmark(times=10,
a <- do.call(rbind, out1),
b <- matrix(unlist(out1), ncol=20, byrow=TRUE),
c <- Reduce(rbind, out1)
)
# Unit: microseconds
# expr min lq
# a <- do.call(rbind, out1) 469.873 479.815
# b <- matrix(unlist(out1), ncol = 20, byrow = TRUE) 257.263 260.479
# c <- Reduce(rbind, out1) 110764.898 113976.376
all.equal(a, b, check.attributes=FALSE)
# [1] TRUE
all.equal(b, c, check.attributes=FALSE)
# [1] TRUE
Zheyuan 是最快的,但就所有意图和目的而言,do.call(rbind())
方法非常相似。
我想运行一个Reduce
代码到out1
一个包含66000个列表元素的列表:
trialStep1_done <- Reduce(rbind, out1)
不过,运行用的时间太长了。我想知道我是否可以在并行计算包的帮助下 运行 这段代码。
我知道有mclapply
、mcMap
,但是我在并行计算包中没有看到像mcReduce
这样的函数。
是否有类似 mcReduce
的函数可用于在 R 中并行执行 Reduce
以完成我想完成的任务?
非常感谢@BrodieG 和@zheYuan Li,你们的回答很有帮助。我认为以下代码示例可以更准确地表示我的问题:
df1 <- data.frame(a=letters, b=LETTERS, c=1:26 %>% as.character())
set.seed(123)
df2 <- data.frame(a=letters %>% sample(), b=LETTERS %>% sample(), c=1:26 %>% sample() %>% as.character())
set.seed(1234)
df3 <- data.frame(a=letters %>% sample(), b=LETTERS %>% sample(), c=1:26 %>% sample() %>% as.character())
out1 <- list(df1, df2, df3)
# I don't know how to rbind() the list elements only using matrix()
# I have to use lapply() and Reduce() or do.call()
out2 <- lapply(out1, function(x) matrix(unlist(x), ncol = length(x), byrow = F))
Reduce(rbind, out2)
do.call(rbind, out2)
# One thing is sure is that `do.call()` is super faster than `Reduce()`, @BordieG's answer helps me understood why.
所以,至此,对于我的200000行数据集,do.call()
很好的解决了问题。
最后,我想知道这是不是更快的方法?或者@ZheYuanLi 用 matrix()
演示的方式可以在这里实现吗?
- 它很慢,因为你反复调用
rbind
。每次调用时,随着对象维度的增加,必须进行新的内存分配。 - 您的工作受内存限制,您不会从并行性中获益。在多核机器上,并行处理仅对 CPU 绑定任务有用。
如果我没有误会你的意思,你应该使用这个:
trialStep1_done <- matrix(unlist(out1), nrow = length(out1), byrow = TRUE)
示例:
out1 <- list(1:4, 11:14, 21:24, 31:34)
#> str(out1)
#List of 4
# $ : int [1:4] 1 2 3 4
# $ : int [1:4] 11 12 13 14
# $ : int [1:4] 21 22 23 24
# $ : int [1:4] 31 32 33 34
trialStep1_done <- matrix(unlist(out1), nrow = length(out1), byrow = TRUE)
#> trialStep1_done
# [,1] [,2] [,3] [,4]
#[1,] 1 2 3 4
#[2,] 11 12 13 14
#[3,] 21 22 23 24
#[4,] 31 32 33 34
感谢@BrodieG 出色的解释和基准测试结果!
我也在我的笔记本电脑上尝试了基准测试,使用与@BrodieG 完全相同的代码,这就是我得到的:
Unit: microseconds
expr min lq mean
a <- do.call(rbind, out1) 653.60 670.36 900.120
b <- matrix(unlist(out1), ncol = 20, byrow = TRUE) 170.16 177.60 224.036
c <- Reduce(rbind, out1) 65589.48 67519.32 72317.812
median uq max neval
745.54 832.36 2352.28 10
183.98 286.84 385.96 10
68897.36 69372.88 108135.96 10
问题不是rbind
,问题是Reduce
。不幸的是,R 中的函数调用非常昂贵,尤其是当您不断创建新对象时。在这种情况下,您调用 rbind
65999 次,每次调用都会创建一个新的 R 对象并添加一行。相反,您可以使用 66000 个参数调用 rbind
一次,这会快得多,因为在内部 rbind
将在 C 中进行绑定,而不必调用 R 函数 66000 次并只分配一次内存。在这里,我们将您的 Reduce
使用与哲源的 matrix/unlist 进行比较,最后将 rbind
使用 do.call
调用一次(do.call
允许您调用一个函数,所有参数指定为列表):
out1 <- replicate(1000, 1:20, simplify=FALSE) # use 1000 elements for illustrative purposes
library(microbenchmark)
microbenchmark(times=10,
a <- do.call(rbind, out1),
b <- matrix(unlist(out1), ncol=20, byrow=TRUE),
c <- Reduce(rbind, out1)
)
# Unit: microseconds
# expr min lq
# a <- do.call(rbind, out1) 469.873 479.815
# b <- matrix(unlist(out1), ncol = 20, byrow = TRUE) 257.263 260.479
# c <- Reduce(rbind, out1) 110764.898 113976.376
all.equal(a, b, check.attributes=FALSE)
# [1] TRUE
all.equal(b, c, check.attributes=FALSE)
# [1] TRUE
Zheyuan 是最快的,但就所有意图和目的而言,do.call(rbind())
方法非常相似。