我在Matlab中有一个矩阵a,如下所示:

a = zeros(10,3);
a(3:6,1)=2; a(5:9,3)=1; a(5:7,2)=3; a(8:10,1)=2;

a =
 0     0     0
 0     0     0
 2     0     0
 2     0     0
 2     3     1
 2     3     1
 0     3     1
 2     0     1
 2     0     1
 2     0     0

我想获得一个单元格数组,其中包含每个数字在列中出现的次数此外,它应该根据元素值进行排序,而不考虑列号在上面的示例中,我想获取单元格:
b = {[5],[4,3],[3]}

因为数字1出现一次5次,数字2在4和3的块中出现两次,数字3出现一次3次正如您所看到的,重复出现是根据元素值而不是元素出现的列的数量排序的。

最佳答案

因为您不关心列,所以可以将所有列串成一个列向量,在每一端用零填充以防止列的开头和结尾的跨距一起运行:

v = reshape(padarray(a, [1 0]), [], 1);
% Or if you don't have the Image Processing Toolbox function padarray...
v = reshape([zeros(1, size(a, 2)); a; zeros(1, size(a, 2))], [], 1);

现在,假设跨距总是由1个或多个零分隔,则可以按如下方式找到每个跨距的长度:
endPoints = find(diff(v) ~= 0);  % Find where transitions to or from 0 occur
spans = endPoints(2:2:end)-endPoints(1:2:end); % Index of transitions to 0 minus
                                               % index of transitions from 0

最后,您可以根据这些跨距中的值来accumulate跨距:
b = accumarray(v(endPoints(1:2:end)+1), spans, [], @(v) {v(:).'}).';

举个例子:
b =

  1×3 cell array

    [5]    [1×2 double]    [3]

注:
结果单元格数组中的值顺序不能保证与spans中的顺序匹配(即上面的b{2}[3 4]而不是[4 3])如果顺序很重要,则需要对下标as per this section of the documentation进行排序下面是如何更改b的计算:
[vals, index] = sort(v(endPoints(1:2:end)+1));
b = accumarray(vals, spans(index), [], @(v) {v(:).'}).';

10-07 17:11