rbind可以在R中并行吗?
当我坐在这里等待一些R脚本运行时…我想知道。。。有没有办法在R中并行rbind 我经常坐着等待这个调用完成,因为我处理大量数据rbind可以在R中并行吗?,r,R,当我坐在这里等待一些R脚本运行时…我想知道。。。有没有办法在R中并行rbind 我经常坐着等待这个调用完成,因为我处理大量数据 do.call("rbind", LIST) 我怀疑你能通过并行化更快地实现这一点:除了你可能必须自己编写之外(第一个线程是rbinds项目1和2,而第二个线程是rbinds项目3和4,等等,当它们完成时,结果是“反弹”,类似这样的-我看不到一种非C方式来改进这一点),这将涉及在线程之间复制大量数据,这通常是一开始就会变慢的事情 在C中,您可以在线程之间共享对象,这样
do.call("rbind", LIST)
我怀疑你能通过并行化更快地实现这一点:除了你可能必须自己编写之外(第一个线程是rbinds项目1和2,而第二个线程是rbinds项目3和4,等等,当它们完成时,结果是“反弹”,类似这样的-我看不到一种非C方式来改进这一点),这将涉及在线程之间复制大量数据,这通常是一开始就会变慢的事情 在C中,您可以在线程之间共享对象,这样您就可以让所有线程在同一内存中写入。祝你好运:——)
最后,作为旁白:rbinding data.frames非常慢。如果您事先知道所有data.frames的结构完全相同,并且它不包含纯字符列,那么您可能可以使用来自的技巧。如果您的data.frame包含字符列,我想您最好先单独处理这些(
do.call(c,lappy(LIST,“[[”,“myCharColName”))
),然后对其余部分执行该技巧,然后再重新组合它们。到目前为止,我还没有找到并行处理的方法。但是对于我的数据集(这是一个大约1500个数据帧的列表,共450万行)下面的代码片段似乎有帮助:
while(length(lst) > 1) {
idxlst <- seq(from=1, to=length(lst), by=2)
lst <- lapply(idxlst, function(i) {
if(i==length(lst)) { return(lst[[i]]) }
return(rbind(lst[[i]], lst[[i+1]]))
})
}
while(长度(lst)>1){
idxlst这里有一个解决方案,它自然扩展到rbind.fill、merge和其他dataframe列表函数:
但就像我所有的答案/问题一样:)
require(降雪)
要求(rbenchmark)
rbinder因为您说过要rbinddata.frame
对象,所以您应该使用data.table
包。它有一个名为rbindlist
的函数,可以极大地增强rbind
。我不是100%确定,但我敢打赌rbind
的任何使用都会在rbindlist
不起作用时触发复制T
无论如何,data.table
是一个data.frame
,所以您不需要尝试任何东西
编辑:
library(data.table)
system.time(dt <- rbindlist(pieces))
utilisateur système écoulé
0.12 0.00 0.13
tables()
NAME NROW MB COLS KEY
[1,] dt 1,000 8 X1,X2,X3,X4,X5,X6,X7,X8,...
Total: 8MB
库(data.table)
system.time(dt这在@Dominik的答案上扩展
我们可以使用并行包中的mclappy来进一步提高速度。另外,rbind.fill比rbind做得更好,所以下面是改进的代码。
注意:这只适用于mac/linux。Windows不支持McLappy。
编辑:如果您想查看进度,请取消对打印(i)行的注释,并确保从终端而不是从RStudio运行。从并行进程打印到RStudio会有点混乱RStudio
library(parallel)
rbind.fill.parallel <- function(list){
while(length(list) > 1) {
idxlst <- seq(from=1, to=length(list), by=2)
list <- mclapply(idxlst, function(i) {
#print(i) #uncomment this if you want to see progress
if(i==length(list)) { return(list[[i]]) }
return(rbind.fill(list[[i]], list[[i+1]]))
})
}
}
库(并行)
rbind.fill.parallel 1){
idxlst看起来很多人已经很好地回答了这个问题,但是如果有人提出了这个问题,下面是一个针对非data.table/data.frame-esque对象的并行rbind版本:
rbind.parallel <- function(list,ncore)
{
library(parallel)
do.call.rbind<-function(x){do.call(rbind,x)}
cl<-makeCluster(ncore)
list.split<-split(list,rep(1:ncore,length(list)+1)[1:length(list)])
list.join<-parLapply(cl,list.split,do.call.rbind)
stopCluster(cl)
list.out<-do.call(rbind,list.join)
return(list.out)
}
plyr软件包中的rbind.parallel宣传它的运行速度比baserbind
快得多。也许你会看到一些性能上的颠簸。如果你添加一些具有代表性的样本数据,人们可以提供其他解决方案以及测试时间的基准。在列表
中有什么类型的对象(矩阵、data.frame等)?列表中有什么类型的对象?Data.frames.dam,它实际上运行得更快!@Arun,这是一个错误,我已经修复了,但它似乎没有保存。你也可以轻松地将其扩展到rbindlist
或其他基于列表的技术。我只是使用Rs standardrbind
来方便地证明概念。@Arun,这不是我的意思。我我从不认为我的并行化解决方案是最快的解决方案。我只是用“是”回答了这个问题:“rbind可以并行化吗?”您可以将这种方法用于不同的函数。通过rbindlist
解决方案,我们很高兴看到它通过并行化得到了改进。这可能不是因为将库/函数“读到核心”比仅仅绑定10公里的帧要花更多的时间。但是10万、1米、10米呢?我现在在我的夏季别墅里,有一台旧的macbook。所以我要到周一才能正确尝试。Ha必须是计算史上速度最快的!在我这方面,从几个小时到不到一秒钟。
rbind.parallel <- function(list,ncore)
{
library(parallel)
do.call.rbind<-function(x){do.call(rbind,x)}
cl<-makeCluster(ncore)
list.split<-split(list,rep(1:ncore,length(list)+1)[1:length(list)])
list.join<-parLapply(cl,list.split,do.call.rbind)
stopCluster(cl)
list.out<-do.call(rbind,list.join)
return(list.out)
}