2014-11-14 53 views
4

我想要做的是:给定一个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]',我不明白为什么。在ix处有3处发生2,处于指数3,69。在那些指数处的iy的对应值是2,34。究竟是创建观察到的订单?这是任意的吗?有没有办法强制它成为我想要的,除了排序Indices之后的每个元素?

回答

2

下面是与arrayfun解决这个问题的一种方法 -

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

显示输出wtih celldisp(idx) -

idx{1} = 
    1  4 
idx{2} = 
    2  3  4 
idx{3} = 
    1  2  4 
idx{4} = 
    2  3 

要继续accumarray工作,你可以用sort包裹iy到得到你想要的输出whi CH不看太漂亮了,也许 -

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 
+0

美丽!我不知道arrayfun。我仍然有点好奇为什么我的尝试方法不起作用,但这似乎是我的实际问题的完美解决方案。 – 2014-11-14 18:26:34

+1

@CurtisH。你的支持很好,这只是'accumarray'不能保持秩序 – 2014-11-14 18:42:17

+0

@CurtisH。我想你可以用'sort'来包装'iy'。为此添加了代码。 – Divakar 2014-11-14 18:47:11

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 
+0

谢谢,这将解释它。我应该更仔细地阅读'accumarray'文件。 – 2014-11-14 19:06:33