如何在MATLAB中将单元阵列中不同大小的矩阵组合成矩阵

时间:2015-07-07 13:01:23

标签: matlab matrix concatenation cell-array

How to combine vectors of different length in a cell array into matrix in MATLAB类似,我想将存储在单元阵列中的具有不同维度的矩阵组合成具有零而不是空白空间的矩阵。具体来说,我有一个单元阵列{1,3}有3个矩阵大小(3,3)(4,3)(4,3):

using (var login = new Login()) {
    login.ShowDialog(this);
}

我想得到类似的东西:

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]}

我尝试使用cellfun和cell2mat,但我不知道如何做到这一点。感谢。

6 个答案:

答案 0 :(得分:5)

即使其他答案都很好,我也想使用cellfun提交我的答案。

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

B = cell2mat(cellfun(@(x) [x;zeros(l-length(x),3)], A, 'UniformOutput', 0));

答案 1 :(得分:2)

使用bsxfun的屏蔽功能 -

%// 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{:}]

示例运行

输入 -

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

答案 2 :(得分:0)

我会使用一个很好的for循环,我认为这非常直观。

以下是注释代码:

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

答案 3 :(得分: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

答案 4 :(得分: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}];

答案 5 :(得分:0)

对于这个特定问题,只需这样做:

B=cat(1,A{:}); 

或者我经常尝试使用 2D 单元格,也适用于您的示例:

B=cell2mat(A'); 

如果你真的没有给出一个 f* 它将被切割的尺寸(而且你非常懒惰):将它放入一个 try-catch-block 并循环覆盖一些暗淡,如下所示。

function A=cat_any(A)
for dims=1:10% who needs more than 10 dims? ... otherwise replace 10 with: max(cellfun(@ndims,in),[],'all')
  try, A=cat(dims,A{:}); end
  if ~iscell(A), return A; end
end
disp('Couldn''t cat!') %if we can't cat, tell the user
end

当心,这可能会导致意想不到的结果......但在大多数情况下,这只是对我有用。