2015-07-07 2 views
1

Аналогично How to combine vectors of different length in a cell array into matrix in MATLAB Я хотел бы объединить матрицу, имеющую разный размер, хранящийся в массиве ячеек, в матрицу, имеющую нули вместо пустых пространств. В частности, у меня есть массив ячеек {1,3}, имеющую 3 матрицу размера (3,3) (4,3) (4,3):Как объединить матрицу разного размера в массив ячеек в матрицу в MATLAB

A={[1 2 3; 4 5 6; 7 8 9] [1 2 3; 4 5 6; 7 8 9; 9 9 9] [1 2 3; 4 5 6; 7 8 9; 4 4 4]} 

и я хотел бы получить что-то вроде:

B = 

1  2  3  1  2  3  1  2  3 
4  5  6  4  5  6  4  5  6 
7  8  9  7  8  9  7  8  9 
0  0  0  9  9  9  4  4  4 

Я пробовал использовать cellfun и cell2mat, но я не понимаю, как это сделать. Благодарю.

ответ

0

Я был бы удивлен, если это возможно, в одной или нескольких линий. Вам, вероятно, придется немного зацикливаться. Ниже добивается того, чего вы хотите в конкретном случае первых несовместимых длинами измерения:

A={[1 2 3; 4 5 6; 7 8 9] [1 2 3; 4 5 6; 7 8 9; 9 9 9] [1 2 3; 4 5 6; 7 8 9; 4 4 4]} 

maxsize = max(cellfun(@(x) size(x, 1), A)); 
B = A; 
for k = 1:numel(B) 
    if size(B{k}, 1) < maxsize 
     tmp = B{k}; 
     B{k} = zeros(maxsize, size(tmp,1)); 
     B{k}(1:size(tmp,1),1:size(tmp,2)) = tmp; 
    end 
end 

B = cat(2, B{:}); 

Теперь B является:

B = 

    1  2  3  1  2  3  1  2  3 
    4  5  6  4  5  6  4  5  6 
    7  8  9  7  8  9  7  8  9 
    0  0  0  9  9  9  4  4  4 
0

Я бы сделал это, используя старый добрый цикл, который довольно интуитивно я думаю.

Вот комментируемого код:

clc;clear var 


A={[1 2 3; 4 5 6; 7 8 9] [1 2 3; 4 5 6; 7 8 9; 9 9 9] [1 2 3; 4 5 6; 7 8 9; 4 4 4]}; 

%// Find the maximum rows and column # to initialize the output array. 
MaxRow = max(cell2mat(cellfun(@(x) size(x,1),A,'Uni',0))); 
SumCol = sum(cell2mat(cellfun(@(x) size(x,2),A,'Uni',0))); 

B = zeros(MaxRow,SumCol); 

%// Create a counter to keep track of the current columns to fill 
ColumnCounter = 1; 
for k = 1:numel(A)  
    %// Get the # of rows and columns for each cell from A 
    NumRows = size(A{k},1); 
    NumCols = size(A{k},2); 

    %// Fill the array 
    B(1:NumRows,ColumnCounter:ColumnCounter+NumCols-1) = A{k}; 

    %// Update the counter 
    ColumnCounter = ColumnCounter+NumCols; 
end 
disp(B) 

Выход:

B = 

    1  2  3  1  2  3  1  2  3 
    4  5  6  4  5  6  4  5  6 
    7  8  9  7  8  9  7  8  9 
    0  0  0  9  9  9  4  4  4 
2

Использования bsxfun «s маскирующей способности -

%// Convert A to 1D array 
A1d = cellfun(@(x) x(:).',A,'Uni',0) %//' 

%// Get dimensions of A cells 
nrows = cellfun('size', A, 1) 
ncols = cellfun('size', A, 2) 

%// Create a mask of valid positions in output numeric array, where each of 
%// those numeric values from A would be put 
max_nrows = max(nrows) 
mask = bsxfun(@le,[1:max_nrows]',repelem(nrows,ncols)) %//' 

%// Setup output array and put A values into its masked positions 
B = zeros(max_nrows,sum(ncols)) 
B(mask) = [A1d{:}] 

Sample пробег

Ввод -

A={[1 2 3 5 6; 7 8 9 3 8] [1 2 3; 4 5 6; 7 8 9; 9 9 9] [1 2 3; 4 5 6; 7 8 9; 4 4 4]} 

Выход -

B = 
    1  2  3  5  6  1  2  3  1  2  3 
    7  8  9  3  8  4  5  6  4  5  6 
    0  0  0  0  0  7  8  9  7  8  9 
    0  0  0  0  0  9  9  9  4  4  4 
5

Даже если другие ответы хороши, я хотел бы представить мое, используя cellfun.

l = max(cellfun(@(x) length(x),A)) 

B = cell2mat(cellfun(@(x) [x;zeros(l-length(x),3)], A, 'UniformOutput', 0)); 
0
[max_row , max_col] = max(size(A{1}) , size(A{2}) , size(A{3})); 
A{1}(end:max_row , end:max_col)=0; 
A{2}(end:max_row , end:max_col)=0; 
A{3}(end:max_row , end:max_col)=0; 
B=[A{1} A{2} A{3}]; 
Смежные вопросы