2016-04-22 55 views
4

我有时间序列,并且我将一些用户定义的函数应用于时间序列中的每个W元素。带滑动窗口元素的矩阵

现在我只是使用for循环,大小为W的幻灯片窗口在每次迭代中将我的函数应用于窗口中的元素。

我使用的Matlab,它是非常低效的“for循环”,所以我很想矢量化这个操作。

作为一种解决方案我看到转化与长度为N的信号,以一个矩阵的大小(N - 1,W),其中每一行是在不同的窗口的时间序列和赋予功能给该矩阵。

所以,我的问题是:

  1. 如何我最初的时间序列转换为这样的矩阵?假设我是步骤X的滑动窗口,所以不会出现(N - 1,W)矩阵,但((N - 1)/ X,W)。

例子([1]矩阵的每个X行):

比方说,我的时间序列是:

T = [1, 5, 6, 8, 10, 14, 22] 
W = 3 
X = 1 

=>我很想得到

[[1, 5, 6], 
[5, 6, 8], 
[6, 8, 10], 
[8, 10, 14], 
[10, 14, 22]] 

如果

W = 3 
X = 2 

=>我很想得到

[[1, 5, 6], 
[6, 8, 10], 
[10, 14, 22]] 
+0

你需要有量化以前更多的先验信息。不过,我没有看到没有for循环的方法...... – 16per9

+1

你需要计算什么样的操作?卷积不会帮助你吗? –

+0

不要很快地解雇循环;有时他们比替代品更快。但是我同意以前的评论,我们需要更多关于你需要在这些窗口上执行的操作的信息。 – beaker

回答

6

创建正确的指标与bsxfun应该肯定帮助:

ind = bsxfun(@plus, 1:W, (0:X:numel(T)-W).'); 
out = T(ind); 

创建正确的指标是第一步,通过代码的第一线划定。这段代码做的是创建一个2D矩阵,其中每行是每个感兴趣的窗口访问的元素。如果您想直观了解代码如何生成索引,请特别注意第一种情况,其中X = 1;W = 3;

我们可以看到,在第一行包括访问元件1,2,的3。第二行包括访问元件2,3,4 ...,直到最后一行,即5,6,7的。我们可以看到,我们需要访问相邻元素在一个窗口,所以基指数需要去从1,2,3,一般为1至W。我们现在需要偏移这些索引,以便它们以每个窗口T中的正确元素为中心。在第一个窗口偏移简直是0,接下来的第二个窗口偏移仅仅是1,直到最后一行是3我们看到,对于每一行,我们1更添加到基础指标作为行增加。因此,我们为第二行的每个基本索引添加1,然后在第三行的每个基本索引添加2,依此类推。如果您将基础索引与偏移量索引相加,那么您最终将获得正确的索引以访问T中的正确元素。

同样,如果X = 2;W = 3;,我们看到我们仍然有基础指数为1,2,3。但是,现在访问的正确元素是第一行1,2,3,然后是3,4,5分别是第二行,然后是5,6,7分别是第三行。对于每一行,我们现在通过而不是1来抵消基础指数。因此,我们将第二行添加到每个基本索引,然后我们将第四行的每个基本索引添加4,依此类推。

通常,使用矢量1:W创建基础索引,并且使用矢量0:X:numel(T)-W创建偏移索引。需要减去W,以便在按照要求对信号进行采样时不会超出范围。要创建我们刚刚讨论过的这些指数,bsxfun可以为我们处理这个问题。

我们创建了一个1:W的行向量,它对应于基本索引和对应于每个窗口的偏移量的(0:X:numel(T)-W).'的列向量。请注意,第一个偏移量从0开始,然后我们增加X的数量,以确保计算正确的中心以将我们的基础指数置于。我们停止,直到我们点击numel(T)-W元素,这是你所说的条件。通过使用bsxfun,创建两个临时2D矩阵,其中行向量被复制为具有与列向量中存在的行一样多的行,并且列向量被复制为与行向量中存在的列数一样多。一旦你将这两个矩阵加在一起,就得到了最终的索引矩阵。

运行与W = 3;X = 1;代码给出:

>> T = [1, 5, 6, 8, 10, 14, 22]; 
>> X = 1; 
>> W = 3; 
>> ind = bsxfun(@plus, 1:W, (0:X:numel(T)-W).') 

ind = 

    1  2  3 
    2  3  4 
    3  4  5 
    4  5  6 
    5  6  7 

同样,如果W = 3;X = 2;我们还可以得到:

>> T = [1, 5, 6, 8, 10, 14, 22]; 
>> X = 2; 
>> W = 3; 
>> ind = bsxfun(@plus, 1:W, (0:X:numel(T)-W).') 

ind = 

    1  2  3 
    3  4  5 
    5  6  7 

您可以验证自己,这些指标对应于正确的元素T在这种情况下创建您想要的矩阵。

最后,我们用它来索引我们的矩阵抢权要素:

out = T(ind); 

做这X = 1;W = 3;给出:

>> out = T(ind) 

out = 

    1  5  6 
    5  6  8 
    6  8 10 
    8 10 14 
    10 14 22 

同样为X = 2;W = 3;给出:

>> out = T(ind) 

out = 

    1  5  6 
    6  8 10 
    10 14 22 
0

基于rayryeng的回答,我编写了一个完全实现这个功能的函数,以及一些附加功能。它设计用于在单变量时间序列上生成自回归指数。通过简单地使用相同的索引并连接引用的数据,它可以很容易地用于多变量情况。

它返回指数,可预测变量X(按您的请求),并用于回归量ý为好。此外,您可以在滑动窗口的同时将“掩码”应用于预测变量X。例如,具有21个以下步骤的窗口中,可以选择[T-2 T-3 T-5 T-8 T-13 T-21] X和T为ý

您还可以更改预测范围 - 未来有多少步骤,指数为。例如X = [T-1 T-2]和ÿ = T + 2

希望别人会发现这是有用的。

% get_Sliding_Indexes: 
%  Useful for autoregression on a univariate time series. 
%  Returns the indexes for the predictor and response variables 
%  according to a sliding window. 
% 
% Copyright (C) 20016 Florin Schimbinschi 
% 
% Parameters: 
%  numRecords - the number of records in the dataset 
% 
%  windowLag - number of past samples to take - it will be equal to 
%   the size of the predictor vector X. Default 10 
% 
%  predHorizon - the prediction horizon is the number of steps into 
%   the future that predictions are to be made. Default 1 
% 
%  windowPattern - by default the window will take all consecutive 
%   values in the past over the window lag size, however it is 
%   possible to sample using a custom pattern. 
%   For example taking every second value can be done by setting 
%   this parameter to 1:2:5. Default 1:windowLag 
% 
%  stepSize - number of steps taken when window is moved. Default 1 
% 
% Returns: 
%  indX - predictor variable indexes 
%  indY - response variable indexes 
% 
% 
%  windowPattern = 1:2:9 __ structure between [] is moved to 
%   / \  / the right by stepSize units 
% >------[(9-7-5-3-1)---(y)]---------------> 
%   \_______/ \_/ 
%   X = [13579] predHorizon = 3 
% 
% 
% Example on a multivariate time series (two) with 6 records: 
% 
%  data2d = [ .1 .2 .3 .4 .5 .6 
%    .11 .22 .33 .44 .55 .66]'; 
% 
%  [X, y] = getSlidingIndexes(size(data2d,1), 4) 
%  X = 
%   1  2  3  4 
%   2  3  4  5 
%  y = 
%   5 
%   6 
% 
%  Assuming we are interested in the second series (column): 
% 
%  series2 = data2d(:,2); 
% 
%  series2(X) 
%  ans = 
%   0.1100 0.2200 0.3300 0.4400 
%   0.2100 0.3300 0.4400 0.5500 
% 
%  series2(y) 
%  ans = 
%   0.5500 
%   0.6600 
% 
function [indX, indY] = get_Sliding_Indexes(numRecords, ... 
         windowLag, predHorizon, windowPattern, stepSize) 

    if ~exist('numRecords','var') || isempty(numRecords) 
     error('The number of records in the dataset is not specified'); 
    end 
    if ~exist('stepSize','var') || isempty(stepSize) 
     stepSize = 1; % steps taken when moving the window 
    end 
    if ~exist('predHorizon','var') || isempty(predHorizon) 
     predHorizon = 1; % aiming to predict this many steps in the future 
    end 
    if ~exist('windowLag','var') || isempty(windowLag) 
     windowLag = 10; % number of time steps to look back 
    end 
    if exist('windowLag','var') && (windowLag > numRecords) 
     error('The size of the window is larger than the number of observations'); 
    end 
    if ~exist('windowPattern','var') || isempty(windowPattern) 
     windowPattern = 1:windowLag; % pattern of sampling data 
    end 
    if exist('windowPattern','var') && windowPattern(end) > windowLag 
     error('The window pattern must stop at the window lag specified'); 
    end 

    % the number of samples in the window 
    maxSample = max(windowPattern); 

    indX = bsxfun(@plus, windowPattern, ... 
     (0:stepSize:(numRecords - maxSample - predHorizon))'); 
    indY = bsxfun(@plus, max(windowPattern) + predHorizon, ... 
     (0:stepSize:(numRecords - maxSample - predHorizon))'); 
end 

你也可以在这里找到代码:https://au.mathworks.com/matlabcentral/fileexchange/58730-get-sliding-indexes-numrecords--windowlag--predhorizon--windowpattern--stepsize-