簡體   English   中英

快速滾動均值+總結

[英]Fast rolling mean + summarize

在R中,我試圖使用不同的窗口寬度對一個大矢量(高達400k元素)進行非常快速的滾動均值,然后對於每個窗口寬度,按每年的最大值匯總數據。 希望下面的例子很清楚。 我嘗試了好幾種方法,並以最快的到現在為止好像是用roll_mean從包裝RcppRoll的運行平均值, aggregate采摘的最大值。 請注意內存需求是一個問題:下面的版本需要非常少的內存,因為它一次只進行一次滾動均值和聚合; 這是首選。

#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

這給出了所需的輸出:包含15行(2001年至2015年)和120列(窗口寬度)的data.frame ,其中包含每個ww和每年的最大值。

但是,計算時間仍然太長(因為我必須計算數千個)。 我嘗試過使用其他選項,即dplyrdata.table ,但由於我對這些軟件包缺乏了解,我一直無法找到更快的東西。

哪個是最快的方法, 使用單個核心 (代碼已在其他地方並行化)?

內存管理,即分配和復制,正在以你的方法殺死你。

這是一個data.table方法,通過引用分配:

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

使用新的frollmean函數(在data.table v1.12.0中添加),您可以執行以下操作

th = setDTthreads(1L)
df[, paste0("D",ww) := frollmean(rawdata, ww, na.rm=TRUE)]
dfsumm <- df[, lapply(.SD, max, na.rm=TRUE), by=year]
setDTthreads(th)

你應該考慮改變你的並行性,因為這個用例在frollmean很好地並行化了。 分組操作也使用並行處理。

您創建的一個性能問題是使用cbind動態增長向量。 您可以嘗試預先分配預期大小,然后使用dfsumm[x] <- y填充它。

暫無
暫無

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

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