簡體   English   中英

滾動平均值/標准偏差(帶條件)

[英]Rolling Mean/standard deviation with conditions

我有一個關於根據條件計算滾動平均值/標准偏差的問題。 老實說,它更多是一個語法問題,但是由於我認為這使我的代碼變慢了很多,所以我認為我應該在這里詢問它是怎么回事。 我有一些財務數據,例如“ Stock Name ,“ Midquotes等列,我想根據股票計算滾動平均值和滾動標准差。

現在,我希望計算每種股票的波動率,這可以通過計算前20個中間報價的滾動標准偏差來完成。 為此,在搜索stackoverflow論壇之后,我發現使用data.table包的一行如下:

DT[, volatility:=( roll_sd(DT$Midquotes, 20, fill=0, align = "right") ), by = Stock]

其中DTdata.table ,其中包含我的所有數據。

現在,這在計算上相當慢,特別是當我將其與典型的滾動標准偏差計算(沒有給出以下任何條件)進行比較時:

DT$volatility <- roll_sd(DT$Midquotes, 20, fill=0, align = "right")

但是,當我嘗試對帶條件的滾動標准偏差執行類似操作時,R將不允許我這樣做:

DT$volatility <- DT[, ( roll_sd(DT$Midquotes, 20, fill=0, align = "right") ), by = Stock]

此行出現錯誤:

Error: cannot allocate vector of size 10.9 Gb

所以我只是想知道,為什么這行: DT[, volatility:=( roll_sd(DT$Midquotes, 20, fill=0, align = "right") ), by = Stock]這么慢? 每次為每種不同的庫存計算滾動標准偏差時,是否可能會復制整個data.table

我認為您的問題是您使用了:=函數,並且在方括號內使用了DT 我認為您的設置是這樣的:

> library(data.table)
> set.seed(83385668)
> DT <- data.table(
+   x     = rnorm(5 * 3), 
+   stock = c(sapply(letters[1:3], rep, times = 5)),
+   time  = c(replicate(3, 1:5)))
> DT
              x stock time
 1:  0.25073356     a    1
 2: -0.24408170     a    2
 3: -0.87475856     a    3
 4:  0.50843761     a    4
 5: -1.91331773     a    5
 6:  0.07850094     b    1
 7: -0.15922989     b    2
 8:  1.09806870     b    3
 9:  0.27995610     b    4
10:  0.45090842     b    5
11:  0.03400554     c    1
12: -0.34918734     c    2
13:  2.16602740     c    3
14: -0.04758261     c    4
15:  1.24869663     c    5

我不確定roll_sd函數來自哪里。 但是,您可以按如下方式使用zoo庫計算滾動平均值:

> library(zoo)
> setkey(DT, stock, time) # make sure data is sorted by time
> DT[, rollmean := rollmean(x, k = 3, fill = 0, align = "right"), 
+    by = .(stock)]
> DT
              x stock time   rollmean
 1:  0.25073356     a    1  0.0000000
 2: -0.24408170     a    2  0.0000000
 3: -0.87475856     a    3 -0.2893689
 4:  0.50843761     a    4 -0.2034676
 5: -1.91331773     a    5 -0.7598796
 6:  0.07850094     b    1  0.0000000
 7: -0.15922989     b    2  0.0000000
 8:  1.09806870     b    3  0.3391132
 9:  0.27995610     b    4  0.4062650
10:  0.45090842     b    5  0.6096444
11:  0.03400554     c    1  0.0000000
12: -0.34918734     c    2  0.0000000
13:  2.16602740     c    3  0.6169485
14: -0.04758261     c    4  0.5897525
15:  1.24869663     c    5  1.1223805

或同等

> DT[, `:=`(rollmean = rollmean(x, k = 3, fill = 0, align = "right")), 
+    by = .(stock)]
> DT
              x stock time   rollmean
 1:  0.25073356     a    1  0.0000000
 2: -0.24408170     a    2  0.0000000
 3: -0.87475856     a    3 -0.2893689
 4:  0.50843761     a    4 -0.2034676
 5: -1.91331773     a    5 -0.7598796
 6:  0.07850094     b    1  0.0000000
 7: -0.15922989     b    2  0.0000000
 8:  1.09806870     b    3  0.3391132
 9:  0.27995610     b    4  0.4062650
10:  0.45090842     b    5  0.6096444
11:  0.03400554     c    1  0.0000000
12: -0.34918734     c    2  0.0000000
13:  2.16602740     c    3  0.6169485
14: -0.04758261     c    4  0.5897525
15:  1.24869663     c    5  1.1223805

現在data.table本身中還有一個滾動均值函數,有關詳細信息,請參見github討論 實現確實非常簡單。

DT[, rollmean := data.table::frollmean(x, n = 3, fill = 0, align = "right"), 
by = .(stock)]

對這兩者進行快速基准測試,表明data.table版本要快一些(大多數情況下)。

library(microbenchmark)

microbenchmark(a = DT[, rollmean := data.table::frollmean(x, n = 3, fill = 0, align = "right"), 
                      by = .(stock)]
               , b = DT[, rollmean := rollmean(x, k = 3, fill = 0, align = "right"),
                            by = .(stock)]
, times = 100L

)

Unit: milliseconds
expr    min      lq     mean  median     uq     max neval cld
   a 1.5695 1.66605 2.329675 1.79340 2.1980 39.3750   100  a 
   b 2.6711 2.82105 3.660617 2.99725 4.3577 20.3178   100   b

我在數據處理過程中遇到了計算滾動標准的相同問題,因此我瀏覽了此站點。 而且我認為您的問題是使用DT $ Midquotes而不是.SD $ Midquotes。 .SD是一個data.table,其中包含每個組的x數據的子集。 而roll_sd函數來自“ RcppRoll”包。 您可以嘗試這種方式。

DT[, (sd = roll_sd(.SD$Midquotes, 20, fill=0, align = "right")), by = .(Stock)]

暫無
暫無

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

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