vec2mat w/ different number of columns

2019-02-26 13:32发布

Referring to Reshape row wise w/ different starting/ending elements number @Divakar came with a nice solution but, what if the number of columns is not always the same?

Sample run -

>> A'
ans =
     4     9     8     9     6     1     8     9     7     7     7     4     6     2     7     1
>> out
out =
     4     9     8     9     0     0
     6     1     8     9     7     7
     7     4     6     2     7     1

I took only the first 4 terms of A and put them in out, then fill the rest 2 empty cell with 0's. So the ncols = [4 6 6]. Unfortunately vet2mat doesn't allow vector as columns number.

Any suggestions?

2条回答
我命由我不由天
2楼-- · 2019-02-26 13:49

You can employ bsxfun's masking capability here -

%// Random inputs
A = randi(9,1,15)
ncols = [4 6 5]

%// Initialize output arary of transposed size as compared to the desired 
%// output arary size, as we need to insert values into it row-wise and MATLAB 
%// follows column-major indexing
out = zeros(max(ncols),numel(ncols)); 

mask =  bsxfun(@le,[1:max(ncols)]',ncols); %//'# valid positions mask for output
out(mask) = A; %// insert input array elements
out = out.' %//'# transpose output back to the desired output array size

Code run -

A =
     5     3     7     2     7     2     4     6     8     1     9     7     5     4     5
ncols =
     4     6     5
out =
     5     3     7     2     0     0
     7     2     4     6     8     1
     9     7     5     4     5     0
查看更多
\"骚年 ilove
3楼-- · 2019-02-26 13:51

You could use accumarray for that:

A = [4 9 8 9 6 1 8 9 7 7 7 4 6 2 7 1].'; %'// data
ncols = [4 6 6]; %// columns
n = max(ncols);
cs = cumsum(ncols);
ind = 1;
ind(cs+1) = 1;
ind = cumsum(ind(1:end-1)); %// `ind` tells the row for each element of A
result = accumarray(ind(:), A(:), [], @(x) {[x; zeros(n-numel(x),1)]}); %// split `A` as 
    %// dictated by `ind`, and fill with zeros. Each group is put into a cell.
result = [result{:}].'; %'// concatenate all cells
查看更多
登录 后发表回答