Rolling-window 列间间隔不同的矩阵
Rolling-window matrix with different intervals between columns
我有一个包含每日数据的 21 年数据向量,我想创建一个 365 天的滚动 window,例如下一个周期在前一个周期之后一个月(30 天)。在问题中,n_interval
定义了下一个 window 的第一个数据点与前一个系列的最后一个观察值之间的差异。
假设我的每日数据从 2000 年 1 月 1 日开始,那么第一列是 2000 年 1 月 1 日到 2001 年 1 月 1 日,第二列从 2000 年 2 月 1 日开始,到 2 月结束. 1, 2001. and ... 最后一列将涵盖 2017 年 1 月 1 日至 2018 年 1 月 1 日。例如如果:
vec = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17]
对于给定变量 n_interval = 3
、with window_size=5
,输出矩阵应如下所示:
mat = [[1 4 7 10 13],
[2 5 8 11 14],
[3 6 9 12 15],
[4 7 10 13 16],
[5 8 11 14 17]]
给定您的示例矢量
vec = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17];
我们可以通过以下方式创建索引方案:
首先,我们需要确定 mat
中将有多少行。假设我们希望 vec
的每个元素至少在 mat
中表达一次,那么我们需要确保最后一行的最后一个索引大于或等于 vec
的大小.很容易看出 mat
中最后一列的索引由
描述
last_index = n_interval*(n_rows-1) + n_columns
我们要确保last_index >= numel(vec)
。将上述表达式代入不等式并求解 n_rows
得到
n_rows >= (numel(vec) - n_columns)/n_interval + 1
我们将 n_rows
指定为该界限的 ceil
,以便它是满足不等式的最小整数。现在我们知道了行数,我们为每行生成起始索引列表
start_index = 1:n_interval:(n_interval*(n_rows-1)+1);
在索引矩阵中,我们希望每一列都是 1 加上前一列。也就是说我们要根据数组 index_offset = 0:(n_interval-1)
.
来偏移列
使用 bsxfun
我们通过计算 start_index
和 index_offset
数组之间所有对的总和来生成索引矩阵
index = bsxfun(@plus, index_offset, start_index');
我们需要担心的最后一件事是越界。为了处理这个问题,我们应用 mod
函数来包装越界指标:
index_wrapped = mod(index-1, numel(vec))+1;
然后我们简单的根据index_wrapped
对向量进行采样
mat = vec(index_wrapped);
完整代码为
n_interval = 3;
n_columns = 5;
vec = 1:17;
n_rows = ceil((numel(vec)-n_columns)/n_interval + 1);
start_index = 1:n_interval:(n_interval*(n_rows-1)+1);
index_offset = 0:(n_columns-1);
index = bsxfun(@plus, index_offset, start_index');
index_wrapped = mod(index-1, numel(vec))+1;
mat = vec(index_wrapped);
我有一个包含每日数据的 21 年数据向量,我想创建一个 365 天的滚动 window,例如下一个周期在前一个周期之后一个月(30 天)。在问题中,n_interval
定义了下一个 window 的第一个数据点与前一个系列的最后一个观察值之间的差异。
假设我的每日数据从 2000 年 1 月 1 日开始,那么第一列是 2000 年 1 月 1 日到 2001 年 1 月 1 日,第二列从 2000 年 2 月 1 日开始,到 2 月结束. 1, 2001. and ... 最后一列将涵盖 2017 年 1 月 1 日至 2018 年 1 月 1 日。例如如果:
vec = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17]
对于给定变量 n_interval = 3
、with window_size=5
,输出矩阵应如下所示:
mat = [[1 4 7 10 13],
[2 5 8 11 14],
[3 6 9 12 15],
[4 7 10 13 16],
[5 8 11 14 17]]
给定您的示例矢量
vec = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17];
我们可以通过以下方式创建索引方案:
首先,我们需要确定 mat
中将有多少行。假设我们希望 vec
的每个元素至少在 mat
中表达一次,那么我们需要确保最后一行的最后一个索引大于或等于 vec
的大小.很容易看出 mat
中最后一列的索引由
last_index = n_interval*(n_rows-1) + n_columns
我们要确保last_index >= numel(vec)
。将上述表达式代入不等式并求解 n_rows
得到
n_rows >= (numel(vec) - n_columns)/n_interval + 1
我们将 n_rows
指定为该界限的 ceil
,以便它是满足不等式的最小整数。现在我们知道了行数,我们为每行生成起始索引列表
start_index = 1:n_interval:(n_interval*(n_rows-1)+1);
在索引矩阵中,我们希望每一列都是 1 加上前一列。也就是说我们要根据数组 index_offset = 0:(n_interval-1)
.
使用 bsxfun
我们通过计算 start_index
和 index_offset
数组之间所有对的总和来生成索引矩阵
index = bsxfun(@plus, index_offset, start_index');
我们需要担心的最后一件事是越界。为了处理这个问题,我们应用 mod
函数来包装越界指标:
index_wrapped = mod(index-1, numel(vec))+1;
然后我们简单的根据index_wrapped
mat = vec(index_wrapped);
完整代码为
n_interval = 3;
n_columns = 5;
vec = 1:17;
n_rows = ceil((numel(vec)-n_columns)/n_interval + 1);
start_index = 1:n_interval:(n_interval*(n_rows-1)+1);
index_offset = 0:(n_columns-1);
index = bsxfun(@plus, index_offset, start_index');
index_wrapped = mod(index-1, numel(vec))+1;
mat = vec(index_wrapped);