Как выполнить накопительную сумму, но сохранить нулевые значения в MATLAB?

Мне нужно сделать кумулятивную сумму в MATLAB для матрицы нулей и единиц для каждой строки, но мне нужно остановить ее, когда больше нет. Пример, если я начну с:

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 ответа

Есть два возможных решения в зависимости от того, как вы хотите обработать случай, когда у вас есть более одной строки из них на строку (если это возможно). Если вы хотите, чтобы накопленная сумма сбрасывалась каждый раз, когда встречается новая строка, используйте более сложное решение. Если вы не хотите, чтобы кумулятивная сумма сбрасывалась для каждой новой строки единиц, или у вас есть только одна строка на строку, используйте более простое решение:

  • Простое решение (сброс одной строки или отсутствие сброса): вы можете выполнить накопленную сумму, а затем использовать A (в частности, его отрицание) в качестве логического индекса для обнуления записей:

    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
    
  • Сложное решение (сбросить сумму для каждой строки): допустим, в строке может быть несколько строк, например (обратите внимание на последнюю строку):

    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
    

    В этом случае мы можем взять значения совокупной суммы в конце каждой строки единиц, поместить их в новую матрицу, применить cummax, а затем вычтите из нашей накопленной суммы:

    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
    

Найдите кумулятивную сумму A и получите позиции нулей в A и замените ноль на эти позиции в cumum.

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 ;
Другие вопросы по тегам