2010-06-23 22 views
2

我要計算的值的累加值中的dat.txt低於那些每串2列第1列的期望的輸出被示爲dat2.txt如何在MATLAB中執行這個累加和?

dat.txt dat2.txt 
1 20  1 20 20 % 20 + 0 
1 22  1 22 42 % 20 + 22 
1 20  1 20 62 % 42 + 20 
0 11  0 11 11 
0 12  0 12 12 
1 99  1 99 99 % 99 + 0 
1 20  1 20 119 % 20 + 99 
1 50  1 50 169 % 50 + 119 

這是我的初始的嘗試:

fid=fopen('dat.txt'); 
A =textscan(fid,'%f%f'); 
in =cell2mat(A); 
fclose(fid); 

i = find(in(2:end,1) == 1 & in(1:end-1,1)==1)+1; 
out = in; 
cumulative =in; 
cumulative(i,2)=cumulative (i-1,2)+ cumulative(i,2); 

fid = fopen('dat2.txt','wt'); 
format short g; 
fprintf(fid,'%g\t%g\t%g\n',[out cumulative(:)]'); 
fclose(fid); 

回答

3

這裏是一個完全矢量(雖然有點混亂的前瞻性),其使用功能CUMSUMlogical indexing一起DIFF產生你想要的結果的解決方案:

>> data = [1 20;... %# Initial data 
      1 22;... 
      1 20;... 
      0 11;... 
      0 12;... 
      1 99;... 
      1 20;... 
      1 50]; 
>> data(:,3) = cumsum(data(:,2));  %# Add a third column containing the 
             %# cumulative sum of column 2 
>> index = (diff([0; data(:,1)]) > 0); %# Find a logical index showing where 
             %# continuous groups of ones start 
>> offset = cumsum(index.*(data(:,3)-data(:,2))); %# An adjustment required to 
                %# zero the cumulative sum 
                %# at the start of a group 
                %# of ones 
>> data(:,3) = data(:,3)-offset;  %# Apply the offset adjustment 
>> index = (data(:,1) == 0);   %# Find a logical index showing where 
             %# the first column is zero 
>> data(index,3) = data(index,2)  %# For each zero in column 1 set the 
             %# value in column 3 to be equal to 
data =         %# the value in column 2 

    1 20 20 
    1 22 42 
    1 20 62 
    0 11 11 
    0 12 12 
    1 99 99 
    1 20 119 
    1 50 169 
+0

非常好的主意! +1 – yuk 2010-06-23 18:49:20

+0

我不知道函數DIFF是否僅適用於測試一個條件?如果我想找到滿足兩個條件的累積和,那麼如何在不使用函數FIND的情況下做到這一點? – Jessy 2010-07-08 07:34:32

0
d=[ 
1 20  
1 22  
1 20  
0 11  
0 12  
1 99  
1 20  
1 50 
]; 
disp(d) 

out=d; 
%add a column 
out(:,3)=0; 

csum=0; 
for(ind=1:length(d(:,2))) 
    if(d(ind,1)==0) 
     csum=0;   
     out(ind,3)=d(ind,2);  
    else 
     csum=csum+d(ind,2); 
     out(ind,3)=csum;  
    end 

end 

disp(out) 
+0

哈希藍色@是它可能只是使用FIND函數而不使用LOOP? – Jessy 2010-06-23 14:49:22

3

不是完全矢量化的解決方案(它循環遍歷順序1的段),但應該更快。它只爲您的數據執行2個循環。使用MATLAB的CUMSUM函數。

istart = find(diff([0; d(:,1)])==1); %# start indices of sequential 1s 
iend = find(diff([d(:,1); 0])==-1); %# end indices of sequential 1s 

dcum = d(:,2); 
for ind = 1:numel(istart) 
    dcum(istart(ind):iend(ind)) = cumsum(dcum(istart(ind):iend(ind))); 
end 

dlmwrite('dat2.txt',[d dcum],'\t') %# write the tab-delimited file 
+0

通過圖像處理工具箱,您可以使用'bwlabel'查找連接的組1' – Jonas 2010-06-23 18:18:36

+0

@Jonas:我記得你從另一個問題的答案中得到了答案。這裏沒有IPT進行測試。無論如何,我的代碼非常簡單。面臨的挑戰是如何在沒有for-loop的情況下爲所有組做cumsum。如果我們在單元陣列中有完整的組,我們可以使用CELLFUN。我會很高興看到一個使用bwlabel的例子,因爲我總是面臨類似的問題。 – yuk 2010-06-23 18:33:11