有没有办法做到以下几点?
我想转一个 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.
答案 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 倍加速。很酷!