zoo::rollmean
to przydatna funkcja, która zwraca średnią kroczącą szeregu czasowego; dla wektora x
o długości n
i wielkości okna k
zwraca wektor c(mean(x[1:k]), mean(x[2:(k+1)]), ..., mean(x[(n-k+1):n]))
.Dlaczego narzędzie zoo :: rollmean jest wolne w porównaniu do prostej implementacji Rcpp?
Zauważyłem, że wydawało się działać powoli z jakiegoś kodu byłem rozwijających się, więc napisałem własną wersję przy użyciu pakietu RCPP i prosty dla pętli:
library(Rcpp)
cppFunction("NumericVector rmRcpp(NumericVector dat, const int window) {
const int n = dat.size();
NumericVector ret(n-window+1);
double summed = 0.0;
for (int i=0; i < window; ++i) {
summed += dat[i];
}
ret[0] = summed/window;
for (int i=window; i < n; ++i) {
summed += dat[i] - dat[i-window];
ret[i-window+1] = summed/window;
}
return ret;
}")
Ku mojemu zdziwieniu, ta wersja funkcja jest znacznie szybsze niż zoo::rollmean
funkcję:
# Time series with 1000 elements
set.seed(144)
y <- rnorm(1000)
x <- 1:1000
library(zoo)
zoo.dat <- zoo(y, x)
# Make sure our function works
all.equal(as.numeric(rollmean(zoo.dat, 3)), rmRcpp(y, 3))
# [1] TRUE
# Benchmark
library(microbenchmark)
microbenchmark(rollmean(zoo.dat, 3), rmRcpp(y, 3))
# Unit: microseconds
# expr min lq mean median uq max neval
# rollmean(zoo.dat, 3) 685.494 904.7525 1776.88666 1229.2475 1744.0720 15724.321 100
# rmRcpp(y, 3) 6.638 12.5865 46.41735 19.7245 27.4715 2418.709 100
przyspieszenie posiada nawet dla znacznie większych wektorów:
# Time series with 5 million elements
set.seed(144)
y <- rnorm(5000000)
x <- 1:5000000
library(zoo)
zoo.dat <- zoo(y, x)
# Make sure our function works
all.equal(as.numeric(rollmean(zoo.dat, 3)), rmRcpp(y, 3))
# [1] TRUE
# Benchmark
library(microbenchmark)
microbenchmark(rollmean(zoo.dat, 3), rmRcpp(y, 3), times=10)
# Unit: milliseconds
# expr min lq mean median uq max
# rollmean(zoo.dat, 3) 2825.01622 3090.84353 3191.87945 3206.00357 3318.98129 3616.14047
# rmRcpp(y, 3) 31.03014 39.13862 42.67216 41.55567 46.35191 53.01875
Dlaczego prosta implementacja Rcpp
działa ~ 100x szybciej niż zoo::rollmean
?
Pakiet 'RcppRoll' oferuje szybsze implementacje' zoo :: roll's. – ExperimenteR