2016-08-12 2 views
2

R에서는 서로 다른 창 너비를 사용하는 큰 벡터 (최대 400k 요소)의 매우 빠른 롤링 평균을 수행하려고합니다. 그런 다음 각 창 너비에 대해 매년 최대 데이터를 요약합니다. . 아래의 예제는 명확하게 알 수 있습니다. 몇 가지 접근법을 시도했으며, 지금까지 가장 빠른 것은 실행 평균에 대해 RcppRoll 패키지에서 roll_mean을 사용하고 최대를 선택하는 데 aggregate을 사용하는 것 같습니다. 메모리 요구 사항이 염려됩니다. 아래 버전에서는 한 번에 하나의 롤링 평균 및 집계를 수행하므로 메모리가 거의 필요하지 않습니다. 이것은 선호된다. data.frame 15 행 및 각 WW의 최대를 포함하는 컬럼 (120) (창 폭) 및 매년 (2001 ~ 2015 년)빠른 롤링 평균 + 요약

#Example data frame of 10k measurements from 2001 to 2014 
n <- 100000 
df <- data.frame(rawdata=rnorm(n), 
       year=sort(sample(2001:2014, size=n, replace=TRUE)) 
       ) 

ww <- 1:120 #Vector of window widths 

dfsumm <- as.data.frame(matrix(nrow=14, ncol=121)) 
dfsumm[,1] <- 2001:2014 
colnames(dfsumm) <- c("year", paste0("D=", ww)) 

system.time(for (i in 1:length(ww)) { 
    #Do the rolling mean for this ww 
    df$tmp <- roll_mean(df$rawdata, ww[i], na.rm=TRUE, fill=NA) 
    #Aggregate maxima for each year 
    dfsumm[,i+1] <- aggregate(data=df, tmp ~ year, max)[,2] 
}) #28s on my machine 
dfsumm 

이 원하는 출력을 제공한다.

그러나 계산에 너무 많은 시간이 걸립니다 (이 중 수천 개를 계산해야하므로). 나는 다른 옵션들, 즉 dplyrdata.table으로 놀아 보려고 노력했지만, 나는 그 패키지에 대한 지식이 부족하기 때문에 더 빠른 것을 찾을 수 없었다.

단일 코어을 사용하는 가장 빠른 방법은 무엇입니까 (이 코드는 이미 다른 곳에서 병렬 처리가되어 있습니까?).

답변

7

메모리 관리, 즉 할당 및 복사가 당신의 접근 방식으로 당신을 죽이고 있습니다. 난 그냥 지금 당신의 제안 (위의 편집 코드를 참조) 다음과 같은 시도했지만 정말 어떤 개선을 볼 않았다

library(data.table) 
setDT(df) 
alloc.col(df, 200) #allocate sufficient columns 

#assign rolling means in a loop 
for (i in seq_along(ww)) 
    set(df, j = paste0("D", i), value = roll_mean(df[["rawdata"]], 
             ww[i], na.rm=TRUE, fill=NA)) 

dfsumm <- df[, lapply(.SD, max, na.rm = TRUE), by = year] #aggregate 
+1

와우! 나는 10 배속의 빠른 속도를 낼 수 있었고, 더 행복 할 수 없었다. 고마워요! – AF7

-1

작성하는 성능 문제 중 하나는 cbind을 사용하여 동적으로 증가하는 벡터를 사용하는 것입니다. 미리 예상 된 크기를 할당하고 나중에 dfsumm[x] <- y을 사용하여 채우도록 시도 할 수 있습니다.

+0

: 여기

은 참조로 할당하는 data.table 접근 방식이다. 100k 샘플을 사용하는 시간은 여전히 ​​28 초입니다. – AF7