如何使用matlab根据索引数组创建k矩阵?

时间:2017-05-14 19:03:05

标签: matlab for-loop matrix

我需要在MatLab中创建具有不同行数的k矩阵。我该怎么办?

假设我有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

因此,如果i的行IDX等于1,我需要将i的行Mpop放在矩阵Mpop1中同样,如果i的行IDX等于2,我需要将i的行Mpop放入矩阵{{} 1}}等等。

我可以这样做

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的任何值,我怎么能这样做?

4 个答案:

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

现在使用此单元格数组的索引来访问Mpop1Mpop2Mpop3Mpop4Mpop5,即使用req{1}req{2}req{3}req{4}req{5}

答案 1 :(得分:1)

如果您的矩阵具有不同的名称,那么通过这种方式您无法做到。然而,实现这一目标的一个好方法可能是使用单元格数组(请参阅this StackOverflow answer)。基本上,所有矩阵都在一个变量中,您可以选择带索引的正确矩阵,在您的情况下为IDX(i)

答案 2 :(得分:1)

作为stated by Sardar Usama,最好使用单元格数组而不是创建动态变量。

这是使用accumarray函数创建没有循环的单元格数组的另一种方法:

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

这将整数从1分成numel(IDX)分组,由IDX中的值决定;将这些指数应用于原始矩阵Mpop;并将生成的子矩阵打包到单元格数组中。

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