2016-03-08 1 views
-1

У меня есть большой набор данных.Лучшая функция приложения для большого набора данных, которая принимает несколько аргументов

Когда я mapply, я получил на этот раз для запуска кода для одного экземпляра (у меня 400 тысяч экземпляров)

user system elapsed 0.49 0.05 0.53 функция принимает 2 аргумента в качестве входных данных.

Получил идею от this ссылки

Есть ли применять функциональные идеи для эффективного выполнения кода?

Edit: Для того, чтобы дать хорошее представление кода

`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 представляет собой кадр данных с 1 миллиарда строк. , которая сама по себе потребляет 0,30 секунды для одного поиска вдоль этого большого кадра данных gh2. Намерение состоит в том, чтобы определить, сколько строк попадает в это состояние Есть ли другой эффективный способ?

+3

Если ваш код неэффективен, просто «применение» не поможет. Если вы хотите ускорить распараллеливание проблемы, см. 'Mcmapply' в пакете' parallel'. Возможно, это тоже полезно: http://stackoverflow.com/questions/8827437/is-there-an-efficient-way-to-parallelize-mapply – fishtank

+0

То же самое произошло. Достигнут небольшой эффективный рычаг. Но не много. – Bharath

ответ

1

Вы все еще не сказали нам достаточно, чтобы повторить свой вопрос, но, возможно, мой пример ниже работает. tl; dr Я могу сэкономить около 10%, заменив sum() на length(which()) (я очень удивлен, что это было не больше ...) и получить 5-кратное ускорение, используя Rcpp.

Сформировать пример данных:

set.seed(101) 
n1 <- 1e4; n2 <- 1e3 
gh2 <- data.frame(data_start=rnorm(n1),data_end=rnorm(n1)) 

Попробуйте как обычные кадры данных и tbl_df из dplyr (также, data_frame является немного более удобным для генерации данных, поскольку она позволяет на лету преобразование).

library("dplyr") 
A <- data_frame(V1=rnorm(n2), 
       V2=V1+runif(n2)) 
A0 <- as.data.frame(A) 

функция первоначально и основа-R альтернатива использования sum():

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 версия. Это почти наверняка может быть сокращено/сделано скользким, но я не очень разбираюсь в этой структуре (вряд ли сделаю огромную разницу в скорости).

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 

Benchmark:

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() составляет 12% быстрее, чем length(which())
  • Rcpp составляет около 5 раз быстрее, чем базовый R

Это может быть в принципе в сочетании с parallel::mcmapply:

mcmapply(fun3,gh2$data_start,gh2$data_end, A$V1,A$V2, 
        mc.cores=4) 

но для размеров в приведенном выше примере накладных расходов является слишком высокой, чтобы сделать его полезным ,

Смежные вопросы