R 拆分 DF 并并行运行测试

标签 r parallel-processing

我有两个矩阵,我想对其进行一些统计,其中我将 dataframe1 与 dataframe2 的每一行进行比较。这些是大型数据框(300,000 行和 40,000 行),因此需要比较很多。

我做了一些函数来应用统计数据。我想知道是否可以将 dataframe1 分割成 block 并在多个核心上并行运行这些 block 。

library(lawstat)
library(reshape2)
df1 = matrix(ncol= 100, nrow=100)
for ( i in 1:100){
  df1[,i] =floor(runif(100, min = 0, max =3))
}

df2 = matrix(ncol= 100, nrow=1000)
for ( i in 1:100){
  df2[,i] =runif(1000, min = 0, max =1000)
}

testFunc<- function(df1, df2){
      x=apply(df1, 1, function(x) apply(df2, 1, function(y) levene.test(y,x)$p.value))
      x=melt(x)
      return(x)
    }

system.time(res <- testFunc(df1,df2 ))

一些统计数据(例如 leven 测试)需要相当长的时间来计算,因此任何可以加快计算速度的方法都会很棒。

最佳答案

您的函数还有优化的空间,但这里是使用 parallel 包进行改进的示例:

library(parallel)
library(snow)

# I have a quad core processor so I am using 3 cores here.
cl <- snow::makeCluster(3)
testFunc2<- function(df1, df2){
  x <- parallel::parApply(cl = cl, X = df1, 1, function(x, df2) apply(df2, 1, 
function(y) lawstat::levene.test(y,x)$p.value), df2)
  x <- melt(x)
  return(x)
}
system.time(res <- testFunc2(df1,df2 ))

在我的机器上,如果集群大小为 3,则运行时间至少会减少一半。

编辑:我对鄙视你的代码感到难过,所以下面是一个精简的 levene.test 函数,它比在大多数家庭/工作机器上并行运行更能提高性能。

lev_lite <- function(y, group){
  N <- 100 # or length(y)
  k <- 3   # or length(levels(group)) after setting to as.factor below
  
  reorder <- order(group)
  group <- group[reorder]
  y <- y[reorder]
  group <- as.factor(group)
  n <- tapply(y,group, FUN = length)
  yi_bar <- tapply(y,group, FUN = median)
  zij <- abs(y - rep(yi_bar, n))
  zidot <- tapply(zij, group, FUN = mean)
  zdotdot <- mean(zij)
  # test stat, see wiki
  W <- ((N - k)/(k - 1)) * (
    sum(n*(zidot - zdotdot)^2)/
      sum((zij - rep(zidot, n))^2))
  
  #p val returned
  1 - pf(W, k-1, N-k)
}

testFunc2 <- function(df1, df2){
  x <- apply(df1, 1, function(x) apply(df2, 1, lev_lite, group = x))
  x <- melt(x)
  return(x)
}

> system.time(res <- testFunc(df1[1:50, ],df2[1:50,] ))
user  system elapsed 
5.53    0.00    5.56 
> system.time(res2 <- testFunc2(df1[1:50, ],df2[1:50, ] ))
user  system elapsed 
1.13    0.00    1.14 
> max(res2 - res)
[1] 2.220446e-15

在没有并行化的情况下,这大约提高了 5 倍。

关于R 拆分 DF 并并行运行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47763768/

相关文章:

c# - Parallel.Invoke 什么时候有用?

使用 for 循环替换非结构化文本文件中的单词

r - R 中的 furrr 包不会继续将工作分散到所有内核?

r - 如何在R中使用knitr创建一个包含代码块和文本的循环

Python cosine_similarity 不适用于具有 NaN 的矩阵

algorithm - 如何使倒排索引搜索更快?

c++ - OpenCV - 如何在我的 LAN 中的单独主机中处理视频的每一帧?

c# - 如何在运行时决定使用 PLINQ 还是 LINQ?

r - 是否可以使用 write.csv() 函数按特定列排序/排序?

R:如何快速地从一个非常大的表格中选择两列中的常用单词或相同数字?