A = [1,4,2,5,10
     2,4,5,6,2
     2,1,5,6,10
     2,3,5,4,2]
我想通过最后一列 A -> B 和 C 将它分成两个矩阵
B =  [1,4,2,5,10
      2,1,5,6,10]
C = [2,4,5,6,2
     2,3,5,4,2]
此外,这种方法可以应用于一个大矩阵,如矩阵 100*22 根据最后一列值通过 matlab 分成 9 组。
使用逻辑索引
B=A(A(:,end)==10,:);
C=A(A(:,end)==2,:);
返回
>> B
B =
     1     4     2     5    10
     2     1     5     6    10
>> C
C =
     2     4     5     6     2
     2     3     5     4     2
编辑:在回复丹的评论时,这里是一般情况的扩展
e = unique(A(:,end));
B = cell(size(e));
for k = 1:numel(e)
    B{k} = A(A(:,end)==e(k),:);
end
或更紧凑的方式
B=arrayfun(@(x) A(A(:,end)==x,:), unique(A(:,end)), 'UniformOutput', false);
因此对于
A =
     1     4     2     5    10
     2     4     5     6     2
     2     1     5     6    10
     2     3     5     4     2
     0     3     1     4     9
     1     3     4     5     1
     1     0     4     5     9
     1     2     4     3     1
你得到单元格数组元素中的矩阵B
>> B{1}
ans =
     1     3     4     5     1
     1     2     4     3     1
>> B{2}
ans =
     2     4     5     6     2
     2     3     5     4     2
>> B{3}
ans =
     0     3     1     4     9
     1     0     4     5     9
>> B{4}
ans =
     1     4     2     5    10
     2     1     5     6    10
    这是一种通用方法,适用于任何大小矩阵的最后一列中的任意数量的数字:
A = [1,4,2,5,10
     2,4,5,6,2
     1,1,1,1,1
     2,1,5,6,10
     2,3,5,4,2
     0,0,0,0,2];
先按最后一列排序(方法很多,不知道这个好不好)
[~, order] = sort(A(:,end));
As = A(order,:);
然后创建一个向量,表示最后一个列中出现了多少行相同的行数(即每组有多少行)
rowDist = diff(find([1; diff(As(:, end)); 1]));
请注意,对于我的示例数据rowDist将等于[1 3 2]1 1、 3 2s 和 2 10s。现在使用mat2cell按这些行分组进行拆分:
Ac = mat2cell(As, rowDist);
如果你真的想要,你现在可以将它分成单独的矩阵(但我怀疑你会这样做)
Ac{:}
结果是
ans =
   1   1   1   1   1
ans =
   0   0   0   0   2
   2   3   5   4   2
   2   4   5   6   2
ans =
    1    4    2    5   10
    2    1    5    6   10
但我认为你会发现Ac它更有用
编辑:
许多解决方案不妨做一个时间比较:
A = [...
     1     4     2     5    10
     2     4     5     6     2
     2     1     5     6    10
     2     3     5     4     2
     0     3     1     4     9
     1     3     4     5     3
     1     0     4     5     9
     1     2     4     3     1];
A = repmat(A, 1000, 1);
tic
for l = 1:100
  [~, y] = sort(A(:,end));
  As = A(y,:);
  rowDist = diff(find([1; diff(As(:, end)); 1]));
  Ac = mat2cell(As, rowDist);
end
toc
tic
for l = 1:100
  D=arrayfun(@(x) A(A(:,end)==x,:), unique(A(:,end)), 'UniformOutput', false);
end
toc
tic
for l = 1:100
  for k = 1:numel(e)
      B{k} = A(A(:,end)==e(k),:);
  end
end
toc
tic
for l = 1:100
  Bb = sort(A(:,end)); 
  [~,b] = histc(A(:,end), Bb([diff(Bb)>0;true]));
  C = accumarray(b, (1:size(A,1))', [], @(r) {A(r,:)} );
end
toc
导致
Elapsed time is 0.053452 seconds.
Elapsed time is 0.17017 seconds.
Elapsed time is 0.004081 seconds.
Elapsed time is 0.22069 seconds.
因此,即使对于大型矩阵,循环方法仍然是最快的。
accumarray结合使用histc:
% Example data (from Mohsen Nosratinia)
A = [...
     1     4     2     5    10
     2     4     5     6     2
     2     1     5     6    10
     2     3     5     4     2
     0     3     1     4     9
     1     3     4     5     1
     1     0     4     5     9
     1     2     4     3     1];
% Get the proper indices to the specific rows
B = sort(A(:,end)); 
[~,b] = histc(A(:,end), B([diff(B)>0;true]));
% Collect all specific rows in their specific groups
C = accumarray(b, (1:size(A,1))', [], @(r) {A(r,:)} );
结果:
>> C{:}
ans =
     1     3     4     5     1
     1     2     4     3     1
ans =
     2     3     5     4     2
     2     4     5     6     2
ans =
     0     3     1     4     9
     1     0     4     5     9
ans =
     2     1     5     6    10
     1     4     2     5    10
注意
B = sort(A(:,end)); 
[~,b] = histc(A(:,end), B([diff(B)>0;true]));
也可以写成
[~,b] = histc(A(:,end), unique(A(:,end)));
但unique不是内置的,因此可能会更慢,尤其是当它全部用于循环时。
还要注意,行的顺序已经改变了它们在原始矩阵中的顺序。如果顺序很重要,您将不得不添加另一个sort:
C = accumarray(b, (1:size(A,1))', [], @(r) {A(sort(r),:)} );