在Matlab中使用列方向零填充将向量重塑为矩阵 [英] Reshape vector to matrix with column-wise zero padding in matlab
问题描述
对于输入矩阵
in = [1 1;
1 2;
1 3;
1 4;
2 5;
2 6;
2 7;
3 8;
3 9;
3 10;
3 11];
我想获取输出矩阵
out = [1 5 8;
2 6 9;
3 7 10;
4 0 11];
意味着我想将第二个输入列重塑为一个输出矩阵,其中将与第一个输入列中一个值相对应的所有值都写入输出矩阵的一列中.
由于在第一输入列中每个值可以有不同数量的条目(此处"1"和"3"有4个值,而"2"只有3个值),因此正常的重塑功能不适用.我需要将所有列填充到最大行数.
您知道如何执行这种matlab式的操作吗?
第二个输入列只能包含正数,因此填充值可以为0
,-x
,NaN
,...
我能想到的最好的方法是基于循环的:
maxNumElem = 0;
for i=in(1,1):in(end,1)
maxNumElem = max(maxNumElem,numel(find(in(:,1)==i)));
end
out = zeros(maxNumElem,in(end,1)-in(1,1));
for i=in(1,1):in(end,1)
tmp = in(in(:,1)==i,2);
out(1:length(tmp),i) = tmp;
end
以下示例中的任何一种都假定 in
的第1列已排序.如果不是这种情况,请首先根据该标准对in
进行排序:
in = sortrows(in,1);
方法1(使用accumarray
)
- 使用
mode
计算所需的行数; - 使用
accumarray
来收集与每个值对应的值列,末尾用零填充.结果是一个单元格; - 水平串联所有单元格的内容.
代码:
[~, n] = mode(in(:,1)); %//step 1
out = accumarray(in(:,1), in(:,2), [], @(x){[x; zeros(n-numel(x),1)]}); %//step 2
out = [out{:}]; %//step 3
或者,可以使用 histc
完成步骤1
n = max(histc(in(:,1), unique(in(:,1)))); %//step 1
或使用accumarray
:
n = max(accumarray(in(:,1), in(:,2), [], @(x) numel(x))); %//step 1
方法2(使用sparse
)
使用 @Dan的答案生成行索引向量,然后使用 sparse
:
a = arrayfun(@(x)(1:x), diff(find([1,diff(in(:,1).'),1])), 'uni', 0); %//'
out = full(sparse([a{:}], in(:,1), in(:,2)));
for an input matrix
in = [1 1;
1 2;
1 3;
1 4;
2 5;
2 6;
2 7;
3 8;
3 9;
3 10;
3 11];
i want to get the output matrix
out = [1 5 8;
2 6 9;
3 7 10;
4 0 11];
meaning i want to reshape the second input column into an output matrix, where all values corresponding to one value in the first input column are written into one column of the output matrix.
As there can be different numbers of entries for each value in the first input column (here 4 values for "1" and "3", but only 3 for "2"), the normal reshape function is not applicable. I need to pad all columns to the maximum number of rows.
Do you have an idea how to do this matlab-ish?
The second input column can only contain positive numbers, so the padding values can be 0
, -x
, NaN
, ...
The best i could come up with is this (loop-based):
maxNumElem = 0;
for i=in(1,1):in(end,1)
maxNumElem = max(maxNumElem,numel(find(in(:,1)==i)));
end
out = zeros(maxNumElem,in(end,1)-in(1,1));
for i=in(1,1):in(end,1)
tmp = in(in(:,1)==i,2);
out(1:length(tmp),i) = tmp;
end
Either of the following approaches assumes that column 1 of in
is sorted, as in the example. If that's not the case, apply this initially to sort in
according to that criterion:
in = sortrows(in,1);
Approach 1 (using accumarray
)
- Compute the required number of rows, using
mode
; - Use
accumarray
to gather the values corresponding to each column, filled with zeros at the end. The result is a cell; - Concatenate horizontally the contents of all cells.
Code:
[~, n] = mode(in(:,1)); %//step 1
out = accumarray(in(:,1), in(:,2), [], @(x){[x; zeros(n-numel(x),1)]}); %//step 2
out = [out{:}]; %//step 3
Alternatively, step 1 could be done with histc
n = max(histc(in(:,1), unique(in(:,1)))); %//step 1
or with accumarray
:
n = max(accumarray(in(:,1), in(:,2), [], @(x) numel(x))); %//step 1
Approach 2 (using sparse
)
Generate a row-index vector using this answer by @Dan, and then build your matrix with sparse
:
a = arrayfun(@(x)(1:x), diff(find([1,diff(in(:,1).'),1])), 'uni', 0); %//'
out = full(sparse([a{:}], in(:,1), in(:,2)));
这篇关于在Matlab中使用列方向零填充将向量重塑为矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!