具有多个参数的大型数据集的最佳应用函数
Best apply function for a large data set which takes multiple arguments
我得到了一个大数据集。
当我使用mapply时,我这次得到了运行一个实例的代码(我有40万个实例)
user system elapsed
0.49 0.05 0.53
函数接受 2 个参数作为输入。
灵感来自 this link
是否有任何应用函数的想法可以有效地 运行 代码?
编辑:给出代码的好主意
`A$V1<- sample(50000)
A$V2<- sample(50000)
output<-mapply(myfun, A$V1, A$V2)
myfun<- function(x,y)
return(length(which(x<=gh2$data_start & y>=gh2$data_end)))`
gh2 是一个包含 10 亿行的数据框。
沿着这个大的 gh2 数据框进行一次搜索,哪个函数本身消耗 0.30 秒。
目的是找出有多少行属于这种情况
还有其他有效的方法吗?
您还没有告诉我们足够多的信息来复制您的问题,但也许我下面的示例可行。 tl;dr 我可以通过用 sum()
代替 length(which())
来节省大约 10%(我很惊讶它没有更多......)并得到一个使用 Rcpp
.
加速 5 倍
生成示例数据:
set.seed(101)
n1 <- 1e4; n2 <- 1e3
gh2 <- data.frame(data_start=rnorm(n1),data_end=rnorm(n1))
尝试常规数据帧和 dplyr
中的 tbl_df
(另外,data_frame
生成数据稍微方便一些,因为它允许即时转换)。
library("dplyr")
A <- data_frame(V1=rnorm(n2),
V2=V1+runif(n2))
A0 <- as.data.frame(A)
使用 sum()
的原始函数和 base-R 替代:
fun1 <- function(x,y)
return(length(which(x<=gh2$data_start & y>=gh2$data_end)))
fun2 <- function(x,y)
return(sum(x<=gh2$data_start & y>=gh2$data_end))
检查:
all.equal(with(A0, mapply(fun1, V1, V2)),
with(A, mapply(fun2, V1, V2))) ## TRUE
现在是 Rcpp
版本。这几乎可以肯定 shortened/made 更流畅,但我对这个框架不是很有经验(不过不太可能产生巨大的速度差异)。
library("Rcpp")
cppFunction("
NumericVector fun3(NumericVector d_start, NumericVector d_end,
NumericVector lwr, NumericVector upr) {
int i, j;
int n1 = lwr.size();
int n2 = d_start.size();
NumericVector res(n1);
for (i=0; i<n1; i++) {
res[i]=0;
for (j=0; j<n2; j++) {
if (lwr[i]<=d_start[j] && upr[i]>=d_end[j]) res[i]++;
}
}
return res;
}
")
检查:
f3 <- fun3(gh2$data_start,gh2$data_end, A$V1,A$V2)
f1 <- with(A0, mapply(fun1, V1, V2))
all.equal(f1,f3) ## TRUE
基准:
library(rbenchmark)
benchmark(fun1.0= with(A0, mapply(fun1, V1, V2)),
fun2.0= with(A0, mapply(fun2, V1, V2)), ## data.frame
fun2 = with(A, mapply(fun2, V1, V2)), ## dplyr-style
fun3 = fun3(gh2$data_start,gh2$data_end, A$V1,A$V2),
columns=c("test", "replications", "elapsed", "relative"),
replications=30
)
## test replications elapsed relative
## 1 fun1.0 30 7.813 5.699
## 3 fun2 30 6.834 4.985
## 2 fun2.0 30 6.841 4.990
## 4 fun3 30 1.371 1.000
data.frame
和tbl_df
区别不大
sum()
比 length(which())
快 12%
- Rcpp 比基础 R 快 5 倍
这原则上可以与parallel::mcmapply
结合使用:
mcmapply(fun3,gh2$data_start,gh2$data_end, A$V1,A$V2,
mc.cores=4)
但是对于上面示例中的大小,开销太高而不值得。
我得到了一个大数据集。
当我使用mapply时,我这次得到了运行一个实例的代码(我有40万个实例)
user system elapsed
0.49 0.05 0.53
函数接受 2 个参数作为输入。
灵感来自 this link
是否有任何应用函数的想法可以有效地 运行 代码?
编辑:给出代码的好主意
`A$V1<- sample(50000)
A$V2<- sample(50000)
output<-mapply(myfun, A$V1, A$V2)
myfun<- function(x,y)
return(length(which(x<=gh2$data_start & y>=gh2$data_end)))`
gh2 是一个包含 10 亿行的数据框。 沿着这个大的 gh2 数据框进行一次搜索,哪个函数本身消耗 0.30 秒。 目的是找出有多少行属于这种情况 还有其他有效的方法吗?
您还没有告诉我们足够多的信息来复制您的问题,但也许我下面的示例可行。 tl;dr 我可以通过用 sum()
代替 length(which())
来节省大约 10%(我很惊讶它没有更多......)并得到一个使用 Rcpp
.
生成示例数据:
set.seed(101)
n1 <- 1e4; n2 <- 1e3
gh2 <- data.frame(data_start=rnorm(n1),data_end=rnorm(n1))
尝试常规数据帧和 dplyr
中的 tbl_df
(另外,data_frame
生成数据稍微方便一些,因为它允许即时转换)。
library("dplyr")
A <- data_frame(V1=rnorm(n2),
V2=V1+runif(n2))
A0 <- as.data.frame(A)
使用 sum()
的原始函数和 base-R 替代:
fun1 <- function(x,y)
return(length(which(x<=gh2$data_start & y>=gh2$data_end)))
fun2 <- function(x,y)
return(sum(x<=gh2$data_start & y>=gh2$data_end))
检查:
all.equal(with(A0, mapply(fun1, V1, V2)),
with(A, mapply(fun2, V1, V2))) ## TRUE
现在是 Rcpp
版本。这几乎可以肯定 shortened/made 更流畅,但我对这个框架不是很有经验(不过不太可能产生巨大的速度差异)。
library("Rcpp")
cppFunction("
NumericVector fun3(NumericVector d_start, NumericVector d_end,
NumericVector lwr, NumericVector upr) {
int i, j;
int n1 = lwr.size();
int n2 = d_start.size();
NumericVector res(n1);
for (i=0; i<n1; i++) {
res[i]=0;
for (j=0; j<n2; j++) {
if (lwr[i]<=d_start[j] && upr[i]>=d_end[j]) res[i]++;
}
}
return res;
}
")
检查:
f3 <- fun3(gh2$data_start,gh2$data_end, A$V1,A$V2)
f1 <- with(A0, mapply(fun1, V1, V2))
all.equal(f1,f3) ## TRUE
基准:
library(rbenchmark)
benchmark(fun1.0= with(A0, mapply(fun1, V1, V2)),
fun2.0= with(A0, mapply(fun2, V1, V2)), ## data.frame
fun2 = with(A, mapply(fun2, V1, V2)), ## dplyr-style
fun3 = fun3(gh2$data_start,gh2$data_end, A$V1,A$V2),
columns=c("test", "replications", "elapsed", "relative"),
replications=30
)
## test replications elapsed relative
## 1 fun1.0 30 7.813 5.699
## 3 fun2 30 6.834 4.985
## 2 fun2.0 30 6.841 4.990
## 4 fun3 30 1.371 1.000
data.frame
和tbl_df
区别不大
sum()
比length(which())
快 12%
- Rcpp 比基础 R 快 5 倍
这原则上可以与parallel::mcmapply
结合使用:
mcmapply(fun3,gh2$data_start,gh2$data_end, A$V1,A$V2,
mc.cores=4)
但是对于上面示例中的大小,开销太高而不值得。