数组 – 从3D单元阵列转换为一组2D矩阵

我有一个3D单元格数组,指定为A {s,i,h},在我的脚本的嵌套循环部分中用作大量数值数据的存储.一些单元格条目将为空白[],而其余单元格由数字组成 – 单数或数组(1 x 10双等):

《数组 – 从3D单元阵列转换为一组2D矩阵》

我想将这个单元格数组转换为一组2D矩阵.

具体地,对于h的每个值,每个值的一个单独的矩阵(h总是等于1:3),并且对于每个s值,每个矩阵中有一列.每列将包含所有组合的数值数据 – 它不需要由i分隔.

我怎么能这样做?我通常使用这种形式处理3D单元阵列,以使用以下内容生成单独的矩阵(每个h值一个):

lens = sum(cellfun('length',reshape(A,[],size(A,3))),1);
max_length = max(lens);
mat = zeros(max_length,numel(lens));
mask = bsxfun(@le,[1:max_length]',lens);
mat(mask) = [A{:}];
mat(mat==0) = NaN;
mat = sort(mat*100);
Matrix1 = mat(~isnan(mat(:,1)),1);
Matrix2 = mat(~isnan(mat(:,2)),2);
Matrix3 = mat(~isnan(mat(:,3)),3);

然而,在这种情况下,每个矩阵只有一列.我无法在每个输出矩阵中添加多个列.

最佳答案 1.结果以矩阵的单元格数组的形式(根据要求)

这是一种可能的方法.我不得不使用一个for循环.但是,如果接受3D阵列结果而不是2D阵列的单元阵列,则可以轻松避免循环.请参阅答案的第二部分.

如果您按照代码中的注释并检查每个步骤的结果,则可以直接了解它的工作原理.

%// Example data
A(:,:,1) = { 1:2, 3:5, 6:9; 10 11:12 13:15 };
A(:,:,2) = { 16:18, 19:22, 23; 24:28, [], 29:30 };

%// Let's go
[S, I, H] = size(A);
B = permute(A, [2 1 3]); %// permute rows and columns
B = squeeze(mat2cell(B, I, ones(1, S), ones(1, H))); %// group each col of B into a cell...
B = cellfun(@(x) [x{:}], B, 'uniformoutput', false); %// ...containing a single vector
t = cellfun(@numel, B); %// lengths of all columns of result
result = cell(1,H); %// preallocate
for h = 1:H
    mask = bsxfun(@le, (1:max(t(:,h))), t(:,h)).'; %'// values of result{h} to be used
    result{h} = NaN(size(mask)); %// unused values will be NaN
    result{h}(mask) = [B{:,h}]; %// fill values for matrix result{h}
end

结果在这个例子中:

A{1,1,1} =
     1     2
A{2,1,1} =
    10
A{1,2,1} =
     3     4     5
A{2,2,1} =
    11    12
A{1,3,1} =
     6     7     8     9
A{2,3,1} =
    13    14    15
A{1,1,2} =
    16    17    18
A{2,1,2} =
    24    25    26    27    28
A{1,2,2} =
    19    20    21    22
A{2,2,2} =
     []
A{1,3,2} =
    23
A{2,3,2} =
    29    30

result{1} =
     1    10
     2    11
     3    12
     4    13
     5    14
     6    15
     7   NaN
     8   NaN
     9   NaN
result{2} =
    16    24
    17    25
    18    26
    19    27
    20    28
    21    29
    22    30
    23   NaN

2.以3D阵列的形式产生结果

如上所述,使用3D阵列存储结果允许避免循环.在下面的代码中,最后三行替换了答案第一部分中使用的循环.其余的代码是一样的.

%// Example data
A(:,:,1) = { 1:2, 3:5, 6:9; 10 11:12 13:15 };
A(:,:,2) = { 16:18, 19:22, 23; 24:28, [], 29:30 };

%// Let's go
[S, I, H] = size(A);
B = permute(A, [2 1 3]); %// permute rows and columns
B = squeeze(mat2cell(B, I, ones(1, S), ones(1, H))); %// group each col of B into a cell...
B = cellfun(@(x) [x{:}], B, 'uniformoutput', false); %// ...containing a single vector
t = cellfun(@numel, B); %// lengths of all columns of result
mask = bsxfun(@le, (1:max(t(:))).', permute(t, [3 1 2])); %'// values of result to be used
result = NaN(size(mask)); %// unused values will be NaN
result(mask) = [B{:}]; %// fill values

这给出(与第一部分的结果比较):

>> result
result(:,:,1) =
     1    10
     2    11
     3    12
     4    13
     5    14
     6    15
     7   NaN
     8   NaN
     9   NaN
result(:,:,2) =
    16    24
    17    25
    18    26
    19    27
    20    28
    21    29
    22    30
    23   NaN
   NaN   NaN
点赞