由accumarray构造的单元阵列中的元素顺序

时间:2014-11-14 18:18:39

标签: matlab matrix cell-array

我正在尝试做什么:给定2D矩阵,获取每行中满足某些特定条件的元素的列索引。

例如,假设我的矩阵是

M = [16 2 3 13; 5 11 10 8; 9 7 6 12; 4 14 15 1]

我的条件是M>6。然后我想要的输出就像是

Indices = {[1 4]'; [2 3 4]'; [1 2 4]'; [2 3]';}

在阅读this similar question的答案后,我使用findaccumarray找到了这个部分解决方案:

[ix, iy] = find(M>6);
Indices = accumarray(ix,iy,[],@(iy){iy});

这几乎给出了我想要的结果 - 事实上,指数是正确的,但它们并没有按我预期的方式排序。例如,Indices{2} = [2 4 3]'代替[2 3 4]',我无法理解原因。 2中有ix次出现3次,索引为369。这些索引的iy的相应值依次为234。究竟是什么创造了观察到的秩序?这是武断的吗?有没有办法强制它成为我想要的,除了事后对Indices的每个元素进行排序?

2 个答案:

答案 0 :(得分:2)

以下是使用 arrayfun 解决问题的一种方法 -

idx = arrayfun(@(x) find(M(x,:)>6),1:size(M,1),'Uni',0)

显示celldisp(idx) -

的输出
idx{1} =
     1     4
idx{2} =
     2     3     4
idx{3} =
     1     2     4
idx{4} =
     2     3

要继续使用accumarray,您可以将iysort一起打包,以获得所需的输出,但看起来并不太漂亮 -

Indices = accumarray(ix,iy,[],@(iy){sort(iy)})

输出 -

>> celldisp(Indices)
Indices{1} =
     1
     4
Indices{2} =
     2
     3
     4
Indices{3} =
     1
     2
     4
Indices{4} =
     2
     3

答案 1 :(得分:2)

accumarray无法保证保留其第二个输入的每个块的顺序(请参阅here,还有here)。但是,当第一个输入已经排序时,它似乎确实保留了它:

[iy, ix] = find(M.'>6); %'// transpose and reverse outputs, to make ix sorted
Indices = accumarray(ix,iy,[],@(iy){iy}); %// this line is the same as yours

产生

Indices{1} =
     1
     4

Indices{2} =
     2
     3
     4

Indices{3} =
     1
     2
     4

Indices{4} =
     2
     3