2017-05-14 129 views
2

我需要在MatLab中創建具有不同行數的k矩陣。我該怎麼做?如何根據使用matlab的索引數組創建一個k矩陣?

Supose我有k=5和我有2矩陣,像那些(該矩陣Mpop可以被看作是任何基質)

Mpop = 
    0.9284 0.9299 -46.3239 1.2597 15.1842 21.8344 68.1583 
    -0.9948 -2.0102 -44.9439 1.7241 15.7423 38.2638 83.2077 
    1.1801 -0.9930 -41.8621 3.5203 14.3528 92.4522 134.3142 
    0.8557 -0.8754 -41.7513 2.7033 13.9570 67.2608 109.0121 
    1.1149 1.9312 -41.6132 2.6042 14.7964 66.1055 107.7187 
    1.1153 0.1656 -41.2766 4.4585 13.8216 120.1216 161.3983 
    -1.1358 -1.9447 -40.9061 1.9565 14.6642 47.1186 88.0247 
    0.0062 -0.2411 -40.4918 1.5405 13.8066 33.3358 73.8276 
    -0.1984 -1.1021 -39.9417 1.2500 13.6128 24.7840 64.7256 
    0.0876 -0.2284 -39.8141 2.2970 13.4819 56.0590 95.8732 

和(IDX是具有值的向量1k

IDX = 
    3 
    4 
    1 
    3 
    2 
    3 
    4 
    5 
    3 
    4 

所以,如果IDXi等於1,我需要把日E行的Mpopi矩陣Mpop1,以同樣的方式,如果行的IDXi等於2,我需要把該行的Mpopi矩陣Mpop2

我可以這樣做

Mpop1 = zeros(10,7); 
Mpop2 = zeros(10,7); 
Mpop3 = zeros(10,7); 
Mpop4 = zeros(10,7); 
Mpop5 = zeros(10,7); 

    for i=1:npop 
     if IDX(i,1)==1 
      Mpop1(i,:) = Mpop(i,:) 
     elseif IDX(i)==2 
      Mpop2(i,:) = Mpop(i,:) 
     elseif IDX(i)==3 
      Mpop3(i,:) = Mpop(i,:) 
     elseif IDX(i)==4 
      Mpop4(i,:) = Mpop(i,:) 
     else IDX(i)==5 
      Mpop5(i,:) = Mpop(i,:) 
     end 
    end 
Mpop1 = Mpop1(all(Mpop1,2),:) 
Mpop2 = Mpop2(all(Mpop2,2),:) 
Mpop3 = Mpop3(all(Mpop3,2),:) 
Mpop4 = Mpop4(all(Mpop4,2),:) 
Mpop5 = Mpop5(all(Mpop5,2),:) 

,但它是不好的,因爲K可以從5被diferent。

那麼,如果我有K的任何值,該怎麼辦?

回答

1

如果您的矩陣具有不同的名稱,那麼您可以通過這種方式進行工作。然而,實現這一點的一個好方法可能是使用單元陣列(關於它們參見this StackOverflow answer)。基本上,你所有的矩陣都會在一個單一的變量中,你可以選擇一個索引的右邊矩陣,在你的情況下這將是IDX(i)

2

創建這5個矩陣是一個壞主意。而是使用單元格數組並使用其索引來訪問/使用特定的矩陣。下面是使用2個循環的溶液:

numIDX = numel(IDX);   %Number of elements of IDX 

tmp = cell(k,numIDX);   %Pre-allocation 
for ii=1:numIDX 
    tmp{IDX(ii),ii}=Mpop(ii,:); %Converted the if-else conditions into a single line 
end 

req = cell(k,1);    %Pre-allocation of the required cell 
for jj=1:k 
    req{jj}=vertcat(tmp{jj,:}); %vertically concatenating/ removing the empty cells of tmp 
end 

現在使用這個單元陣列的索引來訪問即具有req{1}req{2}req{3}req{4},並req{5}分別Mpop1Mpop2Mpop3Mpop4,和Mpop5

+1

爲什麼動態變量/矩陣是一個壞主意?閱讀這裏:http://stackoverflow.com/questions/32467029/how-to-put-these-images-together/32467170#32467170也不要使用'i'和'j'作爲變量名稱。在這裏閱讀爲什麼:http://stackoverflow.com/questions/14790740/using-i-and-j-as-variables-in-matlab –

+0

說了這麼多,如果你真的想分開這些矩陣,在第二個「for」 ('base',['Mpop',num2str(jj)],vertcat(tmp {jj,:}));' –

0

如建議通過juef,使用電池陣列是要走的路:

% define the length of the arrays/matrices 
nID = max(IDX); 
npop = length(IDX); 

% allocate memory 
Mpops = cell(nID, 1); 
[Mpops{:}] = deal(zeros(10,7)); 

% fill the matrices 
for i=1:npop 
    Mpops{IDX(i)}(i, :) = Mpop(i,:); 
end 

% remove empty rows 
for i=1:nID 
    Mpops{i} = Mpops{i}(all(Mpops{i},2),:); 
end 
1

由於stated by Sardar Usama,最好使用一個單元陣列,而不是創建動態的變量。

這裏的另一種方式來創建沒有循環,即單元陣列,採用accumarray功能:

result = accumarray(IDX, (1:numel(IDX)).', [], @(x){Mpop(sort(x),:)}) 

這將來自1到在如由值IDX確定組numel(IDX)整數;將這些指數應用於原始矩陣Mpop;並將產生的子矩陣打包在單元陣列中。

+0

我將如何訪問'Mpop1','Mpop2',等在這​​種情況下? –

+1

@ElcioSilveira就像我的答案一樣。 'result {1}','result {2}',... –

相關問題