让我们考虑我的Matlab代码:
T = 250;
N = 10;
B = 5000;
% starting matrix
Matrix1 = rand(T,N*3,B);
% ending matrix
Matrix2 = nan(T,B*3,N);
% the loop is very slow
for n = 1:(N*3)
for b = 1:B
if n <= 10
Matrix2(:,b,n) = Matrix1(:,n,b);
elseif n <= 20
Matrix2(:,b + B,n - N) = Matrix1(:,n,b);
else
Matrix2(:,b + B + B,n - N - N) = Matrix1(:,n,b);
end
end
end
是否有更有效或更节省时间的方法来得到第二个矩阵?
EDIT
循环可以写成reshape
和permute
操作的组合:
Matrix2 = reshape(permute(reshape(Matrix1, T,N,3,B), [1 4 3 2]), T, B*3, N);
基本答案对于将循环转换为向量化形式很有用:
这是一个矢量化的解:
n = 1:(N*3);
b = 1:B;
% split n based on 3 conditions
n1 = n(n <= 10);
n2 = n(n > 10 & n <= 20);
n3 = n(n > 20);
% the order of dimensions of both arrays should match
Matrix11 = permute(Matrix1, [1,3,2]);
Matrix2(:, b, n1) = Matrix11(:, b, n1);
Matrix2(:, b + B, n2 - N) = Matrix11(:, b, n2);
Matrix2(:, b + B + B, n3 - N - N) = Matrix11(:, b, n3);
指标n
应根据这三个条件分为三个部分。还需要对Matrix1
进行排列,使其维度顺序与Matrix2
的顺序相匹配,以确保向量化赋值正确工作。然而,由于Matrix1
的维序发生了变化,在提取Matrix11
的子集时需要对索引位置重新排序。
等价地,permute
可以应用于每次赋值
n = 1:(N*3);
b = 1:B;
n1 = n(n <= 10);
n2 = n(n > 10 & n <= 20);
n3 = n(n > 20);
Matrix2(:, b, n1) = permute(Matrix1(:, n1, b),[1 3 2]);
Matrix2(:, b + B, n2 - N) = permute(Matrix1(:, n2, b),[1 3 2]);
Matrix2(:, b + B + B, n3 - N - N) = permute(Matrix1(:, n3, b),[1 3 2]);