我想创建一个矩阵
A = [0 0 0 0 1;
0 0 0 1 1;
0 0 0 1 1;
0 0 0 1 1;
0 0 1 1 1;
0 1 1 1 1]
基于一个向量,该向量指示每行上应该有多少个“0”在“1”之前:
B = [4 3 3 3 2 1]
有没有一种无循环的方式来做到这一点?
我想创建一个矩阵
A = [0 0 0 0 1;
0 0 0 1 1;
0 0 0 1 1;
0 0 0 1 1;
0 0 1 1 1;
0 1 1 1 1]
基于一个向量,该向量指示每行上应该有多少个“0”在“1”之前:
B = [4 3 3 3 2 1]
有没有一种无循环的方式来做到这一点?
你没有在你的问题中提到应该如何定义数组的水平大小(个数)。
对于预定义的宽度,您可以使用以下代码:
width = 5;
A = cell2mat(arrayfun(@(x) [ zeros(1,x), ones(1,width-x) ], B, 'UniformOutput', false)');
如果您希望 A 具有最小宽度,但每行仍然至少有一个 1:
A = cell2mat(arrayfun(@(x) [ zeros(1,x), ones(1,max(B)+1-x) ], B, 'UniformOutput', false)');
在没有循环的情况下实现这一点的更短的“老派”方法如下:
A = repmat(B',1,max(B)+1)<repmat([1:max(B)+1],size(B,2),1)
如果你想拥有最少数量的
min_ones=1; %or whatever
A = repmat(B',1,max(B)+min_ones)<repmat([1:max(B)+min_ones],size(B,2),1)
我不知道这与 @nrz 的方法相比如何快速比较(我现在只有 Octave),但对我来说它更直观,因为它只是比较max(B) + min_ones
B 的 * 列平铺:
4 4 4 4 4
3 3 3 3 3
3 3 3 3 3
3 3 3 3 3
2 2 2 2 2
1 1 1 1 1
行平铺 [1 : max(B) + min_ones]
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
生成:
A =
0 0 0 0 1
0 0 0 1 1
0 0 0 1 1
0 0 0 1 1
0 0 1 1 1
0 1 1 1 1
这只需要一行,并且似乎比以前基于repmat
or的解决方案更快arrayfun
:
%// Example data
ncols = 5;
B = [4 3 3 3 2 1];
%// Generate A
A = bsxfun(@gt, 1:ncols, B(:));