簡體   English   中英

如何在SparkR中加速此R代碼

[英]how to speed this R code in SparkR

我有以下代碼可在常規R中使用,但我想移植到SparkR以加快速度:

sample_data<- structure(list(idnty_frst_nm = structure(c(3L, 2L), .Label = c("","I", "Ima"), class = "factor"), idnty_last_nm = structure(c(2L,2L), .Label = c("", "NINJA"), class = "factor"), PERSON_IDENTIFIER_VALUE = c(9021099834,9021099834), RECEIPT_NUMBER = structure(c(2L, 2L), .Label = c("","MISC1234567"), class = "factor"), a_nbr.1 = structure(c(2L,2L), .Label = c("", "A079577094"), class = "factor"), ssn = structure(c(2L,2L), .Label = c("", "123-456-7891"), class = "factor"), idnty_dob = structure(c(2L,2L), .Label = c("", "1/2/2020"), class = "factor"), a_nbr = structure(c(2L,2L), .Label = c("", "AO79577094"), class = "factor")), .Names = c("idnty_frst_nm","idnty_last_nm", "PERSON_IDENTIFIER_VALUE", "RECEIPT_NUMBER","a_nbr.1", "ssn", "idnty_dob", "a_nbr"), row.names = 1:2, class = "data.frame") 

sample_data$name<-paste(sample_data$idnty_frst_nm, sample_data$idnty_last_nm)
innov.df<-sample_data
rownames(innov.df)<-1:nrow(innov.df)

#Checking for duplicate names, using 'agrep' function and storing intermediate 
#results in table 'p'

p<-data.frame(a=integer(),b=integer())
k<-1
for(i in 1:nrow(innov.df)){
  for (j in agrep(innov.df$name[i], innov.df$name,
                  ignore.case=TRUE, value=FALSE,
                  max.distance = 0.07, useBytes = TRUE)) {
    if(i!=j)
    {
      if((innov.df[i,2]==innov.df[j,2])&&(innov.df[i,3]==innov.df[j,3]))
      {
        p[k,1]<-min(i,j)
        p[k,2]<-max(i,j)
        k<-k+1
      }
    }
  }
}

p<-unique(p)

關於如何加快速度的任何想法將不勝感激!!

盡管確實有更好的例子,但這只是一些小例子,說明如何加快該過程。 我試圖維護您的循環結構並對其進行了優化。

而不是在循環中附加到數據框,我將在開頭創建一個列表並為其分配值,最后將它們綁定在一起。 這已經為您帶來了大約40%的加速。

下一個函數僅在第二個if語句中使用as.character() ,因為它們是其他因素。 這帶來了另外10%。

最后一個函數使用矩陣而不是data.frame並將值附加到該矩陣 最后一個實現了上述所有優點:)

到目前為止,還沒有使用過data.tables或應用函數,甚至沒有並行處理,這無疑會進一步加快代碼的速度,但是我敢肯定其他人對此有更豐富的經驗,並且可能會表現出更好的做法。

fdf <- function(){
  p <- data.frame(a=integer(),b=integer())
  for (i in 1:nrow(innov.df)){
    for (j in agrep(innov.df$name[i], innov.df$name, ignore.case=TRUE, value=FALSE,
                    max.distance = 0.07, useBytes = TRUE)) {
      if (i!=j) {
        if ((innov.df[i,2]==innov.df[j,2])&&(innov.df[i,3]==innov.df[j,3])) {
          p[k,1] <- min(i,j)
          p[k,2] <- max(i,j)
          k <- k+1
        }
      }
    }
  }
  p <- data.frame(matrix(p[!is.na(p)],ncol=2, byrow = T))
  colnames(p) <- c("a","b")
  p
}
flist <- function(){
  p <- list()
  for (i in 1:nrow(innov.df)) {
    for (j in agrep(innov.df$name[i], innov.df$name,
                    ignore.case=TRUE, value=FALSE,
                    max.distance = 0.07, useBytes = TRUE)) {
      if (i!=j) {
        if ((innov.df[i,2])==(innov.df[j,2])&&
            (innov.df[i,3])==(innov.df[j,3]))
        {
          p[[k]] <- cbind(a=min(i,j), b=max(i,j))
          k <- k+1
        }
      }
    }
  }
  p <- data.frame(Filter(Negate(is.null), p))
  colnames(p) <- c("a","b")
  p
}
flistOpti <- function(){
  p <- list()
  for (i in 1:nrow(innov.df)) {
    for (j in agrep(innov.df$name[i], innov.df$name,
                    ignore.case=TRUE, value=FALSE,
                    max.distance = 0.07, useBytes = TRUE)) {
      if (i!=j) {
        if (as.character(innov.df[i,"idnty_last_nm"])==as.character(innov.df[j,"idnty_last_nm"]) && 
            (as.character(innov.df[i,"PERSON_IDENTIFIER_VALUE"])==as.character(innov.df[j,"PERSON_IDENTIFIER_VALUE"]))) {

          p[[k]] <- cbind(a=min(i,j), b=max(i,j))
          k <- k+1
        }
      }
    }
  }
  p <- data.frame(Filter(Negate(is.null), p))
  colnames(p) <- c("a","b")
  p
}
fma <- function(){
  p <- matrix(c(a=integer(),b=integer()), ncol=2)
  for (i in 1:nrow(innov.df)){
    for (j in agrep(innov.df$name[i], innov.df$name, ignore.case=TRUE, value=FALSE,
                    max.distance = 0.07, useBytes = TRUE)) {
      if (i!=j) {
        if ((innov.df[i,2]==innov.df[j,2])&&(innov.df[i,3]==innov.df[j,3])) {
          p <- c(p, cbind(min(i,j),max(i,j)))
          k <- k+1
        }
      }
    }
  }
  p <- data.frame(matrix(p[!is.na(p)],ncol=2, byrow = T))
  colnames(p) <- c("a","b")
  p
}
fmaOptim <- function(){
  p <- matrix(c(a=integer(),b=integer()), ncol=2)
  for (i in 1:nrow(innov.df)){
    for (j in agrep(innov.df$name[i], innov.df$name, ignore.case=TRUE, value=FALSE,
                    max.distance = 0.07, useBytes = TRUE)) {
      if (i!=j) {
        if (as.character(innov.df[i,"idnty_last_nm"])==as.character(innov.df[j,"idnty_last_nm"]) && 
           (as.character(innov.df[i,"PERSON_IDENTIFIER_VALUE"])==as.character(innov.df[j,"PERSON_IDENTIFIER_VALUE"]))) {
          p <- c(p, cbind(min(i,j),max(i,j)))
          k <- k+1
        }
      }
    }
  }
  p <- data.frame(matrix(p[!is.na(p)],ncol=2, byrow = T))
  colnames(p) <- c("a","b")
  p
}

library(microbenchmark)
mc <- microbenchmark(times = 1000,
  fdfR = fdf(),
  flistR = flist(),
  flistOptiR = flistOpti(),
  fmaR = fma(),
  fmaOptimR = fmaOptim()
)
mc

Unit: microseconds
       expr     min      lq        mean   median        uq       max neval cld
       fdfR 782.725 831.056 1059.789348 883.3505 1018.7130 24732.664  1000   c
     flistR 449.700 470.089  576.289776 489.5335  545.9820 23600.677  1000  b 
 flistOptiR 394.949 417.227  581.230449 435.1620  492.9325 45357.250  1000  b 
       fmaR 370.784 389.664  484.542990 402.5015  452.3420 24713.785  1000 ab 
  fmaOptimR 313.015 335.670  431.991723 349.8295  393.0620 25033.973  1000 a  

您還可以將nrow(innov.df)放在for(i in 1:nrow(innov.df)) ,因為否則它將計算每個循環中的行數。 這不會導致速度加快,但是示例中的行數僅為2,因此它可能很小,無法顯示出一些改進。 這個小例子表明,隨着行數的增加,需要進行一些小的性能優化。

df <- data.frame(
  x = runif(100000, 1,10),
  id = 1:100000
)

mc <- microbenchmark(times = 1000,
                     Nrow = {for (i in 1:nrow(df)) {}},
                     NoNrow = for (i in 1:100000) {}
)
mc 

Unit: milliseconds
   expr      min       lq        mean    median        uq       max neval cld
   Nrow 3.895500 4.060691 4.311444202 4.1584845 4.3051750 10.454830  1000   b
 NoNrow 3.384633 3.516409 3.734800425 3.6017420 3.7303085 36.621923  1000  a 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM