2013-08-16 64 views
2

我有一個由列向量組成的值爲0或1的矩陣。我希望實現的某種形式的自動化過程創建了一個簡潔的結構來顯示結果。也就是說,該過程將創建結果向量v1,v2,v3,v4,v5,它們對應於每個列變量的每個序列中連續1的數目。如何計算矩陣列中的運行值的長度?

例如d =

0 1 1 1 1 
1 1 0 0 0 
1 1 1 0 1 
0 0 0 0 0 
1 1 0 1 1 

而我們得到 V1 = [2,1] V2 = [3,1] V3 = [1,1] V4 = [1,1] v5 = [1,1,1]

回答

2

這個工作沒有循環。

該代碼應該是不言自明的,否則問我。結果變量是一個單元格數組,因爲每個列的結果具有不同的大小d

nrows = size(d,1); 
d_neg_cell = num2cell(~d,[nrows 1]); 
zeros_d = cellfun(@find, d_neg_cell, 'UniformOutput', 0); 
find_runs = @(v) nonzeros(diff([0; v; nrows+1])-1).'; 
sol = cellfun(find_runs, zeros_d, 'UniformOutput', 0); 

爲了您d矩陣這給:

>> sol{:} 
ans = 
    2  1 
ans = 
    3  1 
ans = 
    1  1 
ans = 
    1  1 
ans = 
    1  1  1 
+0

假設這些列中的一些包含NaN,是否有解決方案來忽略這些NaN,當數據不可用時它被鎖定。謝謝! – user1922730

+0

只需在開始處(在當前第一行之前)添加'd(isnan(d))= 0;'。這將把NaN轉換爲零。 –

+0

對不起,我想我誤解了。如果你有... 1 NaN 1 ...在一列中,你認爲NaN是否打破了1的序列? –

1

遍歷列,添加零來開始和正確的邊緣ditection結束,採取差異,並使用正負值找到位置上升和下降的邊緣。這些位置的不同給你的序列長度。下面是代碼

v = {}; 
for e = d, 
    f = diff([0 e' 0]); 
    v{end+1} = find(f<0) - find(f>0); 
end 

在答覆中由OP返回

>> v{:} 
ans = 
    2  1 
ans = 
    3  1 
ans = 
    1  1 
ans = 
    1  1 
ans = 
    1  1  1 

編輯的評論:

萬一列包含NaN,你想忽略他們,改變線使用差異和通過陣列沒有NaN值:

v = {}; 
for e = d, 
    f = diff([0 e(~isnan(e))' 0]); 
    v{end+1} = find(f<0) - find(f>0); 
end