首页 > 解决方案 > 优化时间序列滞后矩阵的计算

问题描述

我想制作一个由时间序列期望定义的时间序列滞后矩阵n_lags,假设我有一个 50 个周期的样本向量时间序列:

sample_data <- c(0.2486316, 0.2421629, 0.2405042, 0.2438215, 0.2444850, 
0.2481340, 0.2552662, 0.2552662, 0.2504561, 0.2418311,
0.2363576, 0.2343672, 0.2348648, 0.2351966, 0.2380163, 
0.2380163, 0.2373528, 0.2355283, 0.2350307, 0.2333720,
0.2333720, 0.2346990, 0.2325427, 0.2315475, 0.2285620, 
0.2242495, 0.2240836, 0.2265716, 0.2245812, 0.2219274,
0.2212639, 0.2210980, 0.2174490, 0.2172831, 0.2239177, 
0.2212639, 0.2225908, 0.2298889, 0.2338696, 0.2317134,
0.2252447, 0.2295571, 0.2371869, 0.2398408, 0.2423287, 
0.2439874, 0.2468071, 0.2473047, 0.2466412, 0.2479682)

这是我计算时间序列滞后矩阵的自定义函数,我可以在优化中使用最多的是矢量化和预定义的数据框:

time_series_lag_matrix <- function(vector_ts, n_lags=240, limit_length=0, split_response=TRUE){
  library(tictoc)
  tic("Time Needed to extract lags")
  if(length(vector_ts) < limit_length || limit_length <= 0){
    df_lag <- data.frame(matrix(0, nrow=length(vector_ts), ncol=(n_lags+1)))
    for(a in 1:length(vector_ts)){
      df_lag[a,] <- vector_ts[a:(a+n_lags)] 
    } 
  }
  else{
    df_lag <- data.frame(matrix(0, nrow=limit_length, ncol=(n_lags+1)))
    for(a in 1:limit_length){
      df_lag[a,] <- vector_ts[a:(a+n_lags)]
    }
  }
  toc()
  
  name_seq <- paste0("Lags-", rev(1:n_lags))
  colnames(df_lag)[1:n_lags] <- name_seq
  df_lag <- na.omit(df_lag)
  
  if(split_response){
    split <- as.matrix(df_lag[,(n_lags+1)])
    df_lag <- as.matrix(df_lag[,1:n_lags])
    return(list(x=df_lag, y=split))
  }
  else{
    return(as.matrix(df_lag))
  }
}

例如,我使用 n_lags=5,输出将是这样的:

> time_series_lag_matrix(sample_data, n_lags=5)
Time Needed to extract lags: 0.02 sec elapsed
$x
      Lags-5    Lags-4    Lags-3    Lags-2    Lags-1
1  0.2486316 0.2421629 0.2405042 0.2438215 0.2444850
2  0.2421629 0.2405042 0.2438215 0.2444850 0.2481340
3  0.2405042 0.2438215 0.2444850 0.2481340 0.2552662
4  0.2438215 0.2444850 0.2481340 0.2552662 0.2552662
5  0.2444850 0.2481340 0.2552662 0.2552662 0.2504561
6  0.2481340 0.2552662 0.2552662 0.2504561 0.2418311
7  0.2552662 0.2552662 0.2504561 0.2418311 0.2363576
8  0.2552662 0.2504561 0.2418311 0.2363576 0.2343672
9  0.2504561 0.2418311 0.2363576 0.2343672 0.2348648
10 0.2418311 0.2363576 0.2343672 0.2348648 0.2351966
11 0.2363576 0.2343672 0.2348648 0.2351966 0.2380163
12 0.2343672 0.2348648 0.2351966 0.2380163 0.2380163
13 0.2348648 0.2351966 0.2380163 0.2380163 0.2373528
14 0.2351966 0.2380163 0.2380163 0.2373528 0.2355283
15 0.2380163 0.2380163 0.2373528 0.2355283 0.2350307
16 0.2380163 0.2373528 0.2355283 0.2350307 0.2333720
17 0.2373528 0.2355283 0.2350307 0.2333720 0.2333720
18 0.2355283 0.2350307 0.2333720 0.2333720 0.2346990
19 0.2350307 0.2333720 0.2333720 0.2346990 0.2325427
20 0.2333720 0.2333720 0.2346990 0.2325427 0.2315475
21 0.2333720 0.2346990 0.2325427 0.2315475 0.2285620
22 0.2346990 0.2325427 0.2315475 0.2285620 0.2242495
23 0.2325427 0.2315475 0.2285620 0.2242495 0.2240836
24 0.2315475 0.2285620 0.2242495 0.2240836 0.2265716
25 0.2285620 0.2242495 0.2240836 0.2265716 0.2245812
26 0.2242495 0.2240836 0.2265716 0.2245812 0.2219274
27 0.2240836 0.2265716 0.2245812 0.2219274 0.2212639
28 0.2265716 0.2245812 0.2219274 0.2212639 0.2210980
29 0.2245812 0.2219274 0.2212639 0.2210980 0.2174490
30 0.2219274 0.2212639 0.2210980 0.2174490 0.2172831
31 0.2212639 0.2210980 0.2174490 0.2172831 0.2239177
32 0.2210980 0.2174490 0.2172831 0.2239177 0.2212639
33 0.2174490 0.2172831 0.2239177 0.2212639 0.2225908
34 0.2172831 0.2239177 0.2212639 0.2225908 0.2298889
35 0.2239177 0.2212639 0.2225908 0.2298889 0.2338696
36 0.2212639 0.2225908 0.2298889 0.2338696 0.2317134
37 0.2225908 0.2298889 0.2338696 0.2317134 0.2252447
38 0.2298889 0.2338696 0.2317134 0.2252447 0.2295571
39 0.2338696 0.2317134 0.2252447 0.2295571 0.2371869
40 0.2317134 0.2252447 0.2295571 0.2371869 0.2398408
41 0.2252447 0.2295571 0.2371869 0.2398408 0.2423287
42 0.2295571 0.2371869 0.2398408 0.2423287 0.2439874
43 0.2371869 0.2398408 0.2423287 0.2439874 0.2468071
44 0.2398408 0.2423287 0.2439874 0.2468071 0.2473047
45 0.2423287 0.2439874 0.2468071 0.2473047 0.2466412

$y
           [,1]
 [1,] 0.2481340
 [2,] 0.2552662
 [3,] 0.2552662
 [4,] 0.2504561
 [5,] 0.2418311
 [6,] 0.2363576
 [7,] 0.2343672
 [8,] 0.2348648
 [9,] 0.2351966
[10,] 0.2380163
[11,] 0.2380163
[12,] 0.2373528
[13,] 0.2355283
[14,] 0.2350307
[15,] 0.2333720
[16,] 0.2333720
[17,] 0.2346990
[18,] 0.2325427
[19,] 0.2315475
[20,] 0.2285620
[21,] 0.2242495
[22,] 0.2240836
[23,] 0.2265716
[24,] 0.2245812
[25,] 0.2219274
[26,] 0.2212639
[27,] 0.2210980
[28,] 0.2174490
[29,] 0.2172831
[30,] 0.2239177
[31,] 0.2212639
[32,] 0.2225908
[33,] 0.2298889
[34,] 0.2338696
[35,] 0.2317134
[36,] 0.2252447
[37,] 0.2295571
[38,] 0.2371869
[39,] 0.2398408
[40,] 0.2423287
[41,] 0.2439874
[42,] 0.2468071
[43,] 0.2473047
[44,] 0.2466412
[45,] 0.2479682

但是,当我处理更大的时间序列向量时,这将是低效的n_lags,例如处理 4320 的 50K 时间序列向量所需的时间n_lags大约需要 30 分钟或更长时间。

所以我想知道这段代码是否可以用dplyr,tidyr或其他很好的方式编写:

df_lag <- data.frame(matrix(0, nrow=length(vector_ts), ncol=(n_lags+1)))
for(a in 1:length(vector_ts)){
   df_lag[a,] <- vector_ts[a:(a+n_lags)] 
} 

感谢您为这个问题所做的努力!

标签: rmatrixtime-serieslag

解决方案


推荐阅读