2015-08-30 313 views
5

我有一個3D單元陣列,指定爲A{s,i,h},用作我的腳本的嵌套循環部分期間的大量數值數據的存儲。一些細胞的條目爲空白[ ]的,其餘包含數字 - 無論是單數或在陣列(1×10雙等):從三維單元陣列轉換爲一組二維矩陣

enter image description here

欲此單元陣列轉換成一組的二維矩陣。

具體而言,每個值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); 

然而,在這種情況下,每個矩陣只有一列。我無法爲每個輸出矩陣添加多列。

+0

纔可保證您的輸出矩陣的所有列將具有相同的長度?或者你需要定義一個填充值? –

+0

確保它們的長度不會相同 - 因此需要填充。 – AnnaSchumann

+0

另外,你的分組索引是'h'還是'm'還是'i'和'm'?請編輯答案,正如它說'h'和'm',然後'i'和'm' –

回答

2

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 
0

暴力方法:

[num_s, num_i, num_h] = size(A); 
cellofmat = cell(num_h,1); 
for matrix = 1:num_h 
    sizemat = max(cellfun(@numel, A(:,1,matrix))); 
    cellofmat{matrix} = nan(sizemat, num_s); 
    for column = 1:num_s 
     lengthcol = length(A{column, 1, matrix}); 
     cellofmat{matrix}(1:lengthcol, column) = A{column, 1,matrix}; 
    end 
end 
Matrix1 = cellofmat{1}; 
Matrix2 = cellofmat{2}; 
Matrix3 = cellofmat{3}; 

我不知道你的實際結構是什麼樣子,但這個工程的A是使用以下步驟設置。

A = cell(20,1,3); 
for x = 1:3 
    for y = 1:20 
     len = ceil(rand(1,1) * 10); 
     A{y,1,x} = rand(len, 1); 
    end 
end 
+0

被編輯爲修復內部循環索引的錯誤。以前我使用'num_h'而不是'matrix',因此所有3個輸出矩陣都是相同的。 – Matt

相關問題