当我坐在这里等待一些R脚本运行...我想知道...有没有办法在R中并行化rbind?
当我处理大量数据时,我坐着等待这个电话频繁完成.
do.call("rbind", LIST)
Run Code Online (Sandbox Code Playgroud)
小智 24
到目前为止,我还没有找到一种并行方法.但是对于我的数据集(这个是大约1500个数据帧的列表,总计4.5M行),以下代码段似乎有所帮助:
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]]))
})
}
Run Code Online (Sandbox Code Playgroud)
其中lst是列表.它似乎比使用do.call(rbind, lst)或甚至do.call(rbind.fill, lst)(使用plyr包中的rbind.fill)快4倍.在每次迭代中,此代码将数据帧的数量减半.
sta*_*ant 18
因为你说你想要rbind data.frame对象你应该使用该data.table包.它有一个叫做强大rbindlist增强的功能rbind.我不是100%肯定,但我敢打赌任何使用rbind都会触发副本而rbindlist不是.无论如何a 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
Run Code Online (Sandbox Code Playgroud)
闪电快......
Nic*_*bbe 16
我怀疑你可以通过平行化来让它更快地工作:除了你可能必须自己编写它的事实(第一个线程第一个和第2个项目,第二个线程第三个和第四个项目,等等它们已经完成,结果是'反弹',类似的东西 - 我没有看到非C方式改进这个),它将涉及在你的线程之间复制大量数据,这通常是事情这首先是缓慢的.
在C中,您可以在线程之间共享对象,因此您可以将所有线程写入相同的内存中.祝你好运:-)
最后,作为旁白:rbinding data.frames只是很慢.如果您事先知道所有data.frames的结构完全相同,并且它不包含纯字符列,那么您可以使用此答案中的技巧来解决我的一个问题.如果你的data.frame包含字符列,我怀疑你最好单独处理这些(do.call(c, lapply(LIST, "[[", "myCharColName")))然后用其余的处理技巧,之后你可以重新组合它们.
这是一个解决方案,它自然地扩展到rbind.fill,merge和其他数据帧列表函数:
但是像我的所有答案/问题一样验证:)
require(snowfall)
require(rbenchmark)
rbinder <- function(..., cores=NULL){
if(is.null(cores)){
do.call("rbind", ...)
}else{
sequ <- as.integer(seq(1, length(...), length.out=cores+1))
listOLists <- paste(paste("list", seq(cores), sep=""), " = ...[", c(1, sequ[2:cores]+1), ":", sequ[2:(cores+1)], "]", sep="", collapse=", ")
dfs <- eval(parse(text=paste("list(", listOLists, ")")))
suppressMessages(sfInit(parallel=TRUE, cores))
dfs <- sfLapply(dfs, function(x) do.call("rbind", x))
suppressMessages(sfStop())
do.call("rbind", dfs)
}
}
pieces <- lapply(seq(1000), function(.) data.frame(matrix(runif(1000), ncol=1000)))
benchmark(do.call("rbind", pieces), rbinder(pieces), rbinder(pieces, cores=4), replications = 10)
#test replications elapsed relative user.self sys.self user.child sys.child
#With intel i5 3570k
#1 do.call("rbind", pieces) 10 116.70 6.505 115.79 0.10 NA NA
#3 rbinder(pieces, cores = 4) 10 17.94 1.000 1.67 2.12 NA NA
#2 rbinder(pieces) 10 116.03 6.468 115.50 0.05 NA NA
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4148 次 |
| 最近记录: |