2015-09-14 45 views
2

這就是問題:MATLAB - 避免在單元陣列內的矢量重複的值,並採取下一個

我具有形式indx{ii}其中每個ii是大小1xNii(陣列上的單元陣列,這意味着該陣列具有不同的尺寸)。 另一個格式爲indy{jj}的單元陣列,其中每個jj是與ii大小相同的數組。

問題是我想創建一個函數來評估indx{:}數組中的值,並取第一個不重複的值,如果是重複值,則取下一個值。

我會試着用一個例子來解釋。假設我們有indxindy是單元陣列:

indx{1} = [1 3 2 7]; 
indx{2} = [3 8 5]; 
indx{3} = [3 6 2 9]; 
indx{4} = [1 3 4]; 
indx{5} = [3 1 4]; 

indy{1} = [0.12 0.21 0.31 0.44]; 
indy{2} = [0.22 0.34 0.54]; 
indy{3} = [0.13 0.23 0.36 0.41]; 
indy{4} = [0.12 0.16 0.22]; 
indy{5} = [0.14 0.19 0.26]; 

我想要的代碼做的是採取的第一個值和indxindy相當於不重複。因此,對於該示例答案應該是:

ans= 

indx{1} = 1; 
indx{2} = 3; 
indx{3} = 6; 
indx{4} = 4; 
indx{5} = []; 

indy{1} = 0.12; 
indy{2} = 0.22; 
indy{3} = 0.23; 
indy{4} = 0.22; 
indy{5} = []; 

ans,爲indx{1}代碼需要1,因爲是第一次,它不是重複,並採取在indy等值。然後,對於indx{2},它需要3,因爲它是第一個值,並且在之前的任何數組中都不會重複爲第一個值。但對於ind{3}它需要6,因爲重複的第一個值是3,並且在indy(即0.23)中採用等效值6。對於ind{4},第一個和第二個值已重複爲第一個值,因此代碼需要4及其等效的indy。最後,對於indx{5},因爲所有值都已重複,所以代碼應該沒有任何價值。

+3

你試過了一個循環嗎?似乎是一個不錯的選擇...... – thewaywewalk

+0

@thewaywewalk我剛剛發佈了該解決方案。我想知道是否可以通過'cellfun'來完成... – Adriaan

+0

indy {3}的期望返回值是否正確? – excaza

回答

3
indx{1} = [1 3 2 7]; 
indx{2} = [3 8 5]; 
indx{3} = [3 6 2 9]; 
indx{4} = [1 3 4]; 
indx{5} = [3 1 4]; 

indy{1} = [0.12 0.21 0.31 0.44]; 
indy{2} = [0.22 0.34 0.54]; 
indy{3} = [0.13 0.23 0.36 0.41]; 
indy{4} = [0.12 0.16 0.22]; 
indy{5} = [0.14 0.19 0.26]; 

indx2 = NaN(numel(indx),1); 
indx2(1) = indx{1}(1); 
indy2 = NaN(numel(indy),1); 
indy2(1) = indy{1}(1); 
for ii = 2:numel(indx) 
    tmp1 = indx{ii}'; % get the original as array 
    tmp2 = indy{ii}'; 
    if numel(tmp1)>numel(indx2) 
     tmp3 = [indx2;NaN(numel(tmp1)-numel(indx2),1)]; 
     tmp4 = [indx2;NaN(numel(tmp1)-numel(indx2),1)]; 
    else 
     tmp1 = [tmp1;NaN(numel(indx2)-numel(tmp1),1)]; 
     tmp2 = [tmp2;NaN(numel(indx2)-numel(tmp2),1)]; 
     tmp3 = indx2; 
     tmp4 = indy2; 
    end 
    tmp5 = ~ismember(tmp1,tmp3); % find first non equal one 
    tmp6 = find(tmp5,1,'first'); 
    indx2(ii) = tmp1(tmp6); % save values 
    indy2(ii) = tmp2(tmp6); 
end 
N = numel(indx2); 
indx2 = mat2cell(indx2, repmat(1,N,1)); 
N = numel(indy2); 
indy2 = mat2cell(indy2, repmat(1,N,1)); 

indx2 = 

    [ 1] 
    [ 3] 
    [ 6] 
    [ 4] 
    [NaN] 

我在這裏所做的是首先初始化您的輸出單元與原始數據具有相同數量的單元格。然後我分配值1,因爲那個永遠是唯一的,它是第一個條目。之後,我使用for循環首先將所有四個單元格陣列(2個輸入,兩個輸出)轉換爲常規陣列,以便使用ismember進行處理,其中我檢查下一個輸入單元格與您的現有數字之間的所有非相等數字輸出。然後find被用來獲得第一個不匹配的數字。最後,數字被分配給數組(如果存在)。

作爲與NaN使用布爾值的評論,請嘗試NaN ~=NaNNaN ==NaN。第一個會給你1,而第二個會給你零。這質量,使這裏的NaN填料的理想選擇,因爲0 == 0將導致1:

A = [1,2,5,4,NaN]; 
B = [1,3,7,NaN,NaN]; 
ismember(A,B) 
= 

    1  0  0  0  0 

因此,NaN的不等於彼此,因此不會污染您的解決方案。

+0

感謝您的回答。我運行了你的解決方案,它並沒有給我正確的解決方案。 indx2的值除第一個和第二個之外都不正確(你的解決方案給我1; 3; 3; 3; 3,當它應該是1; 3; 6; 4; []),並且在indy2中它們是隻有indy的第一個值,而不是indx的等價值。 –

+0

有趣的錯誤,有趣的修復。查看更新後的答案。 – Adriaan

+0

我試了一下,它的作品完美!謝謝 :)。 –