2016-04-22 100 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-