如何在MATLAB中执行累积求和但保持零值?

时间:2017-06-08 17:21:42

标签: matlab matrix cumsum

我需要在MATLAB中做一个累加和,每行有一个0和1的矩阵,但是当没有更多时,我需要停止它。例如,如果我开始:

A = [0 0 0 0 0 1 1 1 1 1 0 0 0;
     0 0 0 1 1 1 1 1 1 1 0 0 0;
     0 0 0 0 0 0 0 1 1 0 0 0 0];

我想要结果:

B = [0 0 0 0 0 1 2 3 4 5 0 0 0;
     0 0 0 1 2 3 4 5 6 7 0 0 0;
     0 0 0 0 0 0 0 1 2 0 0 0 0];

如果我使用cumsum,它会继续添加值并给出另一个结果:

B = [0 0 0 0 0 1 2 3 4 5 5 5 5;
     0 0 0 1 2 3 4 5 6 7 7 7 7;
     0 0 0 0 0 0 0 1 2 2 2 2 2];

请,如果有人有任何建议,因为我找不到类似的东西(我有几个相当大的矩阵)。

2 个答案:

答案 0 :(得分:4)

有两种可能的解决方案取决于您希望如何处理每行有多个字符串的情况(如果可能的话)。如果希望每次遇到新的字符串时重置累计和,请使用更复​​杂的解决方案。如果您不希望为每个新字符串重置累计和,或者每行只有一个字符串,请使用更简单的解决方案:

  • 简单解决方案(一个字符串或没有重置cumsum):您可以执行累积总和,然后使用A(特别是其negation)作为{ {3}}将条目设置为零:

    B = cumsum(A, 2);
    B(~A) = 0;
    
    B =
    
         0     0     0     0     0     1     2     3     4     5     0     0     0
         0     0     0     1     2     3     4     5     6     7     0     0     0
         0     0     0     0     0     0     0     1     2     0     0     0     0
    
  • 复杂解决方案(为每个字符串重置cumsum):假设每行可以有多个字符串,例如(注意最后一行):

    A =
    
         0     0     0     0     0     1     1     1     1     1     0     0     0
         0     0     0     1     1     1     1     1     1     1     0     0     0
         0     0     0     1     1     0     0     1     1     0     0     0     0
    

    在这种情况下,我们可以在每个字符串的末尾取累积和的值,将它们放在一个新的矩阵中,应用logical index,然后从我们的累积总和中减去:

    B = cumsum(A, 2);
    index = find([zeros(size(A, 1), 1) diff(A, 1, 2)] == -1);
    C = zeros(size(B));
    C(index) = B(index);
    B = B-cummax(C, 2);
    
    B =
    
         0     0     0     0     0     1     2     3     4     5     0     0     0
         0     0     0     1     2     3     4     5     6     7     0     0     0
         0     0     0     1     2     0     0     1     2     0     0     0     0
                                                   ^-- sum resets
    

    在这种情况下应用更简单的解决方案会产生:

    B =
    
         0     0     0     0     0     1     2     3     4     5     0     0     0
         0     0     0     1     2     3     4     5     6     7     0     0     0
         0     0     0     1     2     0     0     3     4     0     0     0     0
                                                   ^-- no reset
    

答案 1 :(得分:-1)

在A中找到A的累积和并获得零的位置,并在cumsum中的这些位置替换零。

A = [0 0 0 0 0 1 1 1 1 1 0 0 0;
     0 0 0 1 1 1 1 1 1 1 0 0 0;
     0 0 0 0 0 0 0 1 1 0 0 0 0];

B = cumsum(A,2) ;
B(A==0) = 0 ;