如何在 MATLAB 中执行此累积和?

发布于 2024-09-07 05:26:59 字数 719 浏览 6 评论 0原文

我想计算下面 dat.txt 第 2 列中第 1 列中每个字符串的值的累积和。所需的输出显示为 dat2.txt

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);

I want to calculate a cumulative sum of the values in column 2 of dat.txt below for each string of ones in column 1. The desired output is shown as dat2.txt:

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

Here's my initial attempt:

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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰魂雪魄 2024-09-14 05:26:59

这是一个完全矢量化的(尽管看起来有点令人困惑)解决方案,它使用函数 CUMSUMDIFF 沿逻辑索引产生你想要的结果:

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

Here's a completely vectorized (albeit somewhat confusing-looking) solution that uses the functions CUMSUM and DIFF along with logical indexing to produce the results you want:

>> 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
转身以后 2024-09-14 05:26:59

不是完全矢量化的解决方案(它循环遍历连续 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

Not completely vectorized solution (it loops through the segments of sequential 1s), but should be faster. It's doing only 2 loops for your data. Uses MATLAB's CUMSUM function.

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
浅听莫相离 2024-09-14 05:26:59
    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)
    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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文