我正在尝试做什么:给定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的答案后,我使用find
和accumarray
找到了这个部分解决方案:
[ix, iy] = find(M>6);
Indices = accumarray(ix,iy,[],@(iy){iy});
这几乎给出了我想要的结果 - 事实上,指数是正确的,但它们并没有按我预期的方式排序。例如,Indices{2} = [2 4 3]'
代替[2 3 4]'
,我无法理解原因。 2
中有ix
次出现3次,索引为3
,6
和9
。这些索引的iy
的相应值依次为2
,3
和4
。究竟是什么创造了观察到的秩序?这是武断的吗?有没有办法强制它成为我想要的,除了事后对Indices
的每个元素进行排序?
答案 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
,您可以将iy
与sort
一起打包,以获得所需的输出,但看起来并不太漂亮 -
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