【问题标题】:MATLAB how to perform cumsum which fulfill two conditions?MATLAB如何执行满足两个条件的cumsum?
【发布时间】:2010-07-08 08:34:08
【问题描述】:

这个问题与How can I perform this cumulative sum in MATLAB?有关。

是否可以使用两个条件来执行 cumsum?还是只有一个条件?

已编辑:

data = [1 22 20;...  %# Initial data
        1 22 22;...
        1 22 20;...
        1 44 11;...
        0 44 12;...
        1 33 99;...
        1 33 20;...
        1 33 50];

我想找到满足两个条件的累积和:

% 1) current row in column 1 = 1 && previous row in column 1==1;
% 2) current row in column 2 = previous row in column 2

data(:,4) = cumsum(data(:,3)); % Add a 4th column containing 
                               % the cumulative sum of column 3
index  = diff([0;data(:,1)])> 0 && diff([0;data(:,2); 0])~= 0; 
offset = cumsum(index.*(data(:,4)-data(:,3)));  
data(:,4) = data(:,4)-offset;        
index = (data(:,1) == 0); 
data(index,4) = data(index,3) 

预期输出:

data = [1 22 20 20   >> 20 + 0
        1 22 20 40   >> 20 + 20
        1 44 11 84   >> 11 + 40
        0 44 12 12   >> 12 + 0
        1 33 99 99   >> 99 + 0
        1 33 20 119  >> 20 + 99
        0 33 50 50   >> 50 + 0

编辑: 使用下面的代码,我得到了错误的输出。

index = diff([0;data(:,1)])> 0 & diff([0;data(:,2)])~=0

 1    22    20    20
 1    22    22    42
 1    22    20    62
 1    44    11    73 %this supposed to be 11 not 73 ..
 0    44    12    12
 1    33    99    99
 1    33    20   119
 1    33    50   169

【问题讨论】:

  • 您的代码会产生什么错误?如果您不告诉我们,我们会发现(更)难以诊断您的问题。您的数据样本也会有所帮助。
  • ??? || 的操作数和 && 运算符必须可转换为逻辑标量值。
  • 您似乎真的想要一种分段累积总和,也就是说,每次第 2 列发生变化时,累积总和就开始计算——这是否正确?
  • 另外,为什么data(3,4) = 84 在你的例子中?不应该是11data(4,4) = 11 吗?

标签: matlab cumulative-sum


【解决方案1】:

我很慢,还没有真正理解你想要做什么。你能用语言来形容吗?做的时候,把你要操作的数组数据的哪些元素的指定,和累计和的指定分开 Matlab函数cumsum不带任何条件,你要写Matlab语句来选择你要操作的数据想先求和。

您的第二个条件data(1:end-1)==data(2:end) 在我看来很可疑,因为他们使用线性索引,这可能不是您想要的。如果您不理解线性索引这个术语,请尝试使用一些引用,例如 data(4) 和 data(24),即二维数组中的一维索引。

所以声明

index = diff([0;data(:,1)])> 0 && diff([0;data(:,2); 0])~= 0;

引发错误。你需要做的是交互式地使用 Matlab 来构建你想要逐段执行的语句。那么,

[0;data(:,1)]

产生你期望的结果?你了解它产生什么吗?接下来,问同样的问题

diff([0;data(:,1)])

然后是

diff([0;data(:,1)])> 0

并继续前进。在某些时候,您会发现 Matlab 并没有达到您的预期——这是因为您的预期是错误的。

最后,绝对错误的一件事是子表达式diff([0;data(:,1)])> 0diff([0;data(:,2); 0])~= 0 产生不同长度的向量。

编辑: 运算符 & 可能是您想要的,因为它将在您的两个数组上逐个元素地操作。

编辑 2:恐怕我没有更多时间来帮助您解决这个问题,所以我建议您重写您的程序以显式循环数据数组以构建累积和.

【讨论】:

  • 谢谢。实际上我想找到一个累积总和,第 1 列中的行 = 1,第 2 列中的当前行 = 第 2 列中的前一行
  • @Jessy:我不明白你的评论。您要对哪些列求和,要匹配哪些列?所有这些?
  • 抱歉给您带来了困惑。我已经改变了输出。我要求和的列是第 3 列,我想匹配第 1 列和第 2 列。第 1 列中的当前行 = 第 1 列中的当前行,第 2 列中的当前行 == 第 2 列的前一行。跨度>
【解决方案2】:

按照你写的问题(只满足你所拥有的两个条件),你需要一个这样的索引表达式:

index = data(:,1) & ([0;diff(data(:,2))] == 0);

请注意,这适用于满足您的两个条件(以下重申)的累积总和:

  1. 第 1 列为 1 的行
  2. 第 2 列与前一行匹配或为第一行的行

对我来说,这会产生

data(index,4) = cumsum(data(index,3))
data =

     1    22    20    20
     1    22    22    42
     1    22    20    62
     1    44    11     0
     0    44    12     0
     1    33    99     0
     1    33    20    82
     1    33    50   132

也就是说,这不会产生您想要的输出,因此您的条件或想要的输出是错误的。

【讨论】:

    猜你喜欢
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 2014-04-30
    • 2018-12-21
    相关资源
    最近更新 更多