如何将元胞数组中不同大小的矩阵组合成MATLAB中的矩阵

How to combine matrix of different size in a cell array into a matrix in MATLAB

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

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,但我不知道该怎么做。谢谢

我会使用古老的 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

如果这可以在一行或几行中实现,我会感到惊讶。您可能需要自己做一些循环。在第一维长度不兼容的特定情况下,以下实现了您想要的:

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

使用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

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

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

B = cell2mat(cellfun(@(x) [x;zeros(l-length(x),3)], A, 'UniformOutput', 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}];

对于这个具体问题,只需这样做:

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

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

B=cell2mat(A'); 

如果你真的不给 f* 它将被切入的维度(而且你非常懒惰):将相同的放入 try-catch-block 并循环一些 dims,如下所示。

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

注意,这可能会导致意想不到的结果......但在大多数情况下,这对我来说很管用。