我有一对非常大的data.frames df1& df2(> 500,000行)具有不同的行数,两者都包含相同的4列(X,Y,Z坐标和计数属性)。 Doomie的例子:
df1<-data.frame(x=c(3,5,2,4),y=c(8,5,7,6),z=c(13,15,12,10),
count=c(10,20,4,12))
df2<-data.frame(x=c(4,3,6),y=c(6,9,8),z=c(10,13,15),count=c(4,7,3))
我想仅为匹配XYZ(相同空间点)的行减去计数列(df1$count - df2$count
)。我找到了一种方法,通过使用函数merge() {base}
来实现它,但它很慢并且df非常大。
任何提示我怎么能让它更快?我应该尝试引入并行处理吗?任何提示如何与这样的例子并行执行它而不需要在块中切割df?
感谢。
我的实施:
df3<-merge(df1,df2,by.x=c("x","y", "z"),by.y=c("x","y", "z"),all.x=T,all.y=TRUE)
df3[is.na(df3$count.x),4]<-0
df3[is.na(df3$count.y),5]<-0
df3$countdif<-df3$count.y-df3$count.x
新编辑。 答案: Akrun的答案中的2条建议工作正常。第一个在微基准测试中的速度提高了2倍,并且也适用于我的大型数据帧。这里是他们的基准:
使用dplyr {}
dodplyr<- function (a,b){
dfN<- full_join(a,b, by=c('x', 'y', 'z')) %>%
mutate_each(funs(replace(., which(is.na(.)), 0)),
starts_with('count')) %>%
mutate(countdif= count.y-count.x)
dfN<-select(dfN,-count.x,-count.y)
return(dfN)
}
并使用data.table {}
dodata.table<-function(a,b){
setDT(a)
setDT(b)
DT <- merge(a,b, by=c('x', 'y', 'z'), all=TRUE)
for(j in 4:5){set(DT, i=which(is.na(DT[[j]])), j=j, value=0)}
DT[, countdif:= count.y-count.x]
DT[,c("count.x","count.y"):=NULL]
return(DT)
}
微基准测试:
times <- microbenchmark( dodplyr(df1,df2), dodata.table(df1,df2), times=1e3)
> times
Unit: milliseconds
expr min lq mean median uq max neval
dodplyr(df1, df2) 2.374164 2.489710 2.978814 2.590829 2.704017 18.15356 1000
dodata.table(df1, df2) 5.094271 5.308994 6.458764 5.534259 5.675328 37.23370 1000
但是我无法将它们与使用merge {base}和dfs的实现进行比较。我尝试包含它,但在调用microbenchmark时遇到错误。在这里我尝试了:
domerge<- function(a,b){
dfm<-merge(a,b,by.x=c("x","y", "z"),by.y=c("x","y", "z"),all.x=T,all.y=TRUE)
dfm[is.na(dfm$count.x),4]<-0
dfm[is.na(dfm$count.y),5]<-0
dfm$countdif<-dfm$count.y-dfm$count.x
dfm<-dfm[,c(1:3,6)]
return(dfm)
}
在调用时可以正常工作,例如df3<-domerge(df1,df2)
但是在微基准测试时会出错:
> times <- microbenchmark(domerge(df1,df2), dodplyr(df1,df2), dodata.table(df1,df2), times=1e3)
Show Traceback
Rerun with Debug
Error in merge.data.table(a, b, by.x = c("x", "y", "z"), by.y = c("x", :
Can not match keys in x and y to automatically determine appropriate `by` parameter. Please set `by` value explicitly.
答案 0 :(得分:0)
你必须创建一个像这个例子一样减去的算法:
(如果他们有一个独立的ALU)
y=1
while y <= "end.of.y"
Core one > df1={1,1,y} - df2={1,1,y}
//you subtract the y until the end of y column is reached
//saving in another matrix called as you want, then
Core two > df1={1,1,y+1} - df2={1,1,y+1}
...
Core eight > df1={1,1,y+7} - df2={1,1,y+7}
y=y+8
endwhile
对另一个轴x和z(嵌套循环循环)执行相同操作。直到他们的目的结束。
如果您只在处理器中有4个ALU,则必须执行相同操作,但仅使用4个核心&#39;
我希望这会有所帮助。