说我有以下矩阵:
A(:,1) = [-5 -5 5 5 -5 -5 -5 -5 5 5 5 5]';
A(:,2) = [8 7 3 6 5 9 8 7 9 4 3 2 ]';
我想根据第一栏中的标志将其分成4组(即标志翻转前的所有内容都是一组):
1)-5 -5
2)5 5
3)-5 -5 -5 -5
4)5 5 5 5
然后第二列中的相应分组将是:
1)8 7
2)3 6
3)5 9 8 7
4)9 4 3 2
我的直觉是使用
diff(A(:,1)) ~= 0
作为第一步,但我不确定如何从那里继续。任何帮助将不胜感激,谢谢!
答案 0 :(得分:2)
您可以使用accumarray
为您创建此单元格数组。我们首先需要为共享符号的连续数字的每个“组”分配唯一值。然后我们可以使用accumarray
将给定组中的所有元素放入单元格数组的元素中。
A = cat(1, [-5 -5 5 5 -5 -5 -5 -5 5 5 5 5], [8 7 3 6 5 9 8 7 9 4 3 2 ]).';
% Compute the sign of each element: -1 for negative, 1 for positive
% Repeat first element for diff
S = sign(A([1 1:end],1));
% -1 -1 -1 1 1 -1 -1 -1 -1 1 1 1 1
% Compute element-by-element differences
D = diff(S);
% 0 0 2 0 -2 0 0 0 2 0 0 0
% Convert to a logical matrix which will make any non-zero 1 and any zero stays 0
L = logical(D);
% 0 0 1 0 1 0 0 0 1 0 0 0
% Take the cumulative sum (and add 1) to give each group of elements a unique number
subs = cumsum(L) + 1;
% 1 1 2 2 3 3 3 3 4 4 4 4
% Use this as the first input to accumarray and perform a given action on all elements in
% A(:,2) which share these values. Our action will be to convert to a cell array
result = accumarray(subs, A(:,2), [], @(x){x});
% result{1} =
% 8 7
%
% result{2} =
% 3 6
%
% result{3} =
% 5 9 8 7
%
% result{4} =
% 9 4 3 2
如果我们真的想减少它,那么我们可以做到这一点。
accumarray(1 + cumsum(logical(diff(sign(A([1 1:end],1))))), A(:,2), [], @(x){x})
答案 1 :(得分:1)
这是另一种方式:
result = mat2cell(A(:), diff([0; find([diff(sign(A(:))); true])]));
这使用mat2cell
将A
分成几部分并将每个部分放入一个单元格中。使用sign
计算部分的长度以检测符号,然后使用diff
和find
来计算运行长度。
答案 2 :(得分:1)
使用:
groupsSizes= diff([0;find(conv(A(:,1),[1,-1],'same')~=0)]);
firstGroup = mat2cell(A(:,1),groupsSizes,1);
secondGroup = mat2cell(A(:,2),groupsSizes,1);