如何在matlab中从数组创建等价类

时间:2015-03-29 07:23:16

标签: arrays matlab

我正在处理matlab并拥有一个数组:

a =   
2 1 5 3 2 1 2 1

您可以看到多次可能有一个值。我想要一个函数,它会为每个值提供一个数组,其中包含数组中该值的索引作为输出。

使用上面的例子,输出将是:

(1 5 7)
(2 6 8)
(3) 
(4)

(1 5 7)是输入数组中的索引2。 1.5和3也是如此。

这可以使用for loops等来完成。我只想知道matlab中是否有一些内置函数。


**** 编辑 ****

可能有两列如下。

2 1 5 3 2 1 2 1
3 4 3 2 4 4 3 4

在这种情况下,输出将是

(1 7)
(2 6 8)
(3)
(4)
(5)

3 个答案:

答案 0 :(得分:3)

我认为没有内置功能可以执行此操作,但您可以使用uniquearrayfun:

在一行中执行此操作
Res = arrayfun(@(x) find(x==a), unique (x, 'stable'), 'UniformOutput', false);

最佳,

答案 1 :(得分:3)

使用unique的第三个输出为a的每列获取唯一标签,然后使用自定义函数应用accumarray

[~, ~, kk] = unique(a.', 'rows', 'stable'); %'
result = accumarray(kk, (1:numel(kk)).', [], @(x) {sort(x).'});

这适用于任意数量的行。对于你的两行示例

a = [2 1 5 3 2 1 2 1
     3 4 3 2 4 4 3 4];

结果是

result{1} =
     1     7
result{2} =
     2     6     8
result{3} =
     3
result{4} =
     4
result{5} =
     5

如果元素顺序不重要,您可以稍微简化代码:

[~, ~, kk] = unique(a.', 'rows'); %'
result = accumarray(kk, (1:numel(kk)).', [], @(x) {x.'});

给出了

result{1} =
     2     8     6
result{2} =
     7     1
result{3} =
     5
result{4} =
     4
result{5} =
     3

答案 2 :(得分:2)

扩展Ratbert的不错答案,以获得一个更为通用的答案,以解决"编辑的#34;请求:

[~, ~, J]= unique(a.', 'rows');
Res = cellfun(@str2num,accumarray(J,[1:size(a,2)]',[], @(x)num2str(x),'uni',0);

使用从double到char和back的转换是笨重的,但它适用于Octave 3.6.4,并且也适用于MATLAB。在MATLAB中,使用accumarray可能会有更优雅的答案。


编辑:以下是accumarray更优雅的答案(详见MATLAB文档) - 相当于LuisMendo的答案。

[~, ~, J]= unique(a.', 'rows');
Res = accumarray(J,[1:numel(J)]',[],@(x){x});