2014-11-14 40 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