matlab数组到“堆叠”矩阵

时间:2021-04-23 01:49:30

标签: matlab

有没有办法做到以下几点?

我想转一个 MATLAB 数组:

>> (1:10)'

ans =

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10

进入以下顺序矩阵(我不确定它的名称是什么):

ans =

   NaN   NaN   NaN     1
   NaN   NaN   NaN     2
   NaN   NaN   NaN     3
     1     2     3     4
     2     3     4     5
     3     4     5     6
     4     5     6     7
     5     6     7     8
     6     7     8     9
     7     8     9    10

我可以使用以下函数执行此操作,但它会遍历每一行并且速度很慢:

function V = vec2stack(X, num_sequences)
    
n = numel(X);

len_out = n - num_sequences + 1;

V = zeros(len_out,num_sequences);

for kk = 1:len_out
    V(kk,:) = X(kk:kk +num_sequences - 1)';
end
V = [nan(num_sequences,num_sequences); V(1:end-1,:)];
end

X = 1:10;
AA = vec2stack(X,3)

为长度为 1,000,000 的向量运行上述函数大约需要 1 秒,这对我来说还不够快,

tic;
Lag = vec2stack(1:1000000,5);
toc;

Elapsed time is 1.217854 seconds.

1 个答案:

答案 0 :(得分:2)

您可以使用 repmat() 水平重复 X 向量。然后,请注意每一列都比前一列多一列。您可以添加一个与矩阵具有相同列数的行向量,Matlab 会将向量广播到整个矩阵上并为您进行加法。

在旧版本的 Matlab 中,您可能需要显式 repmat() 行向量以使形状匹配。

function V = vec2stack(X, num_sequences)

    % Repeat X, 1 time vertically, num_seq times horizontally
    % X(:) ensures it's a column vector so we have the correct shape
    mat = repmat(X(:), 1, num_sequences);
    
    % make a row vector from 0:num_sequences-1
    vec = 0:(num_sequences-1);
    
    % or explicitly repmat on vec if you need to:
    % vec = repmat(0:(num_sequences-1), numel(X), 1);
    
    % Add the two. Matlab broadcasts the row vector onto the matrix
    % Because they have the same number of columns
    mat = mat + vec;
    
    % Build the return matrix
    V = [nan(num_sequences, num_sequences); mat];

end

X = (1:10)';
AA = vec2stack(X,3)

% You can easily add the last column as another column

测试速度Octave Online

%% Loopy version
tic;
Lag = vec2stack(1:1000000,5);
toc;

Elapsed time is 17.4092 seconds
%% Vectorized version
tic;
Lag = vec2stack((1:1000000)',5);
toc;

Elapsed time is 0.110762 seconds.

~150 倍加速。很酷!

相关问题