滚动窗矩阵,列之间的间隔不同

时间:2018-01-13 20:27:45

标签: matlab matrix vector sliding-window

我有一个21年的数据向量,包含每日数据,并希望创建一个365天的滚动窗口,例如下一个周期的星期一个月(30天)之后的星期。在问题中,n_interval定义了下一个窗口的第一个数据点与前一个系列的最后一个数据点之间的差异。

让我们假设我的日常数据从2000年1月1日开始,然后第一列将是2000年1月1日 - 2001年1月1日,第二列从2000年2月1日开始。结束在2001年2月1日。...最后一栏将涵盖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 = 3with 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]]

1 个答案:

答案 0 :(得分:2)

给出你的示例向量

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_indexindex_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);