Arrays MATLAB:基于条件的可变大小的移动积分器(和)窗口

Arrays MATLAB:基于条件的可变大小的移动积分器(和)窗口,arrays,matlab,indexing,cumsum,Arrays,Matlab,Indexing,Cumsum,我想根据数组值的累积和来定义移动积分器(sum)窗口的开始和结束索引。每个窗口的累积总和应小于或等于阈值 此窗口的end\u索引在未来窗口中均匀向前移动1,但是start\u索引取决于数组的值开始索引可以向前移动、保持不变或向后移动(负值),因此此移动窗口的大小不是固定的 例如: array=[1201201011] 当start\u index=1时,对于第一个窗口,array的累积和在end\u index=5时为5 现在,对于下一个窗口,end_索引向前移动1,这样新的end_索引=6。我

我想根据
数组
值的累积和来定义移动积分器(sum)窗口的开始和结束索引。每个窗口的累积总和应小于或等于阈值

此窗口的
end\u索引
在未来窗口中均匀向前移动1,但是
start\u索引
取决于
数组
的值<代码>开始索引可以向前移动、保持不变或向后移动(负值),因此此移动窗口的大小不是固定的

例如:

array=[1201201011]

start\u index=1
时,对于第一个窗口,
array
的累积和在
end\u index=5
时为5

现在,对于下一个窗口,
end_索引
向前移动1,这样新的
end_索引=6
。我想知道如何通过从新的
end\u索引
反向计算累积和来找到新的
start\u索引
,以便新窗口的
cumsum
也小于或等于5。在这种情况下,新的
start\u索引=4

关于如何做到这一点有什么建议吗


谢谢。

要查找任何给定开始索引的结束索引:

start_index = 2;
threshold = 20;

if(sum(start_index:end)<threshold) %Error checking
    end_index = -1; 
else 
    end_index = find(cumsum(array(start_index:end)) >= threshold,1) + start_index - 1;
end 
start\u索引=2;
阈值=20;
如果(总和(开始索引:结束)=阈值,1)+开始索引-1;
结束
要查找任何给定结束索引的开始索引,请执行以下操作:

end_index = 6;
threshold = 20;

if(sum(1:end_index)<threshold) %Error checking
    start_index = -1; 
else
    start_index = end_index + 1 - find(cumsum(fliplr(array(1:end_index))) >= threshold,1);

end %Error checking
end_索引=6;
阈值=20;
if(总和(1:结束指数)=阈值,1);
结束%错误检查

这个想法是,如果我们想从一个起始索引
k
中获得累计和,就不需要再次计算累计和。取而代之的是,只计算了一个C,而指定的累计和是原始累计和和的第k-1个元素和原始累计和的差值

original_Summ = [1 1 3 4 5 7 7 7 8 10 10 11 11 12 13]
k=3
new_Summ = original_Summ - original_Summ(k-1)
注意:如果
数组
的大小过大,以下实现可能会导致内存限制。相反,每个cmp和cmp1应该在每次迭代中完成

array = [ 1 0 2 1 1 2 0 0 1  2 0  1  0  1  1 ];
%forward cumsum
fwd = cumsum(array);
%backward cumsum
bkw = cumsum(array(end:-1:1));%cumsum(array,'reverse')
%difference of cumulative sum with all starting indices
cmp = bsxfun(@minus,fwd,[0 fwd(1:end-1)].');%in matlab r2016b cmp= fwd-[0 fwd(1:end-1)].'
cmp1= bsxfun(@minus,bkw,[0 bkw(1:end-1)].');%in matlab r2016b cmp1=bkw-[0 bkw(1:end-1)].'
%find last indices of elements  that are <=5
[r, c] = find(cmp <=5);
idx = accumarray(r,c,[],@max);
[r1, c1] = find(cmp1 <=5);
idx1 = accumarray(r1,c1,[],@max);
idx1 =flipud(numel(array) + 1-idx1);
%loop to find indices from previous indices
si = 1;
index={};
while true
    ei = idx(si);
    if ei == numel(array)
        break;
    end
    index {end+1} = [si,ei];
    ei = ei+1;
    si = idx1(ei);
    index {end+1} = [si,ei];
end
disp(index)
array=[12012001];
%远期累积金额
fwd=累积和(阵列);
%向后积温
bkw=cumsum(数组(end:-1:1));%总和(数组,'reverse')
%累积和与所有起始指数的差值
cmp=bsxfun(@负,前向,[0前向(1:end-1)]);%在matlab r2016b中,cmp=fwd-[0 fwd(1:end-1)]。'
cmp1=bsxfun(@减号,bkw,[0 bkw(1:end-1)]);%在matlab r2016b中,cmp1=bkw-[0 bkw(1:end-1)]。'

%查找当前元素的最后索引我很难理解您所说的“…我想返回计算以查找新的
start\u索引”
…”。你能举个数字例子吗?rayryeng,对不起,描述不清楚。对于第一种情况,
sum
数组
的前向累积和。一旦我找到
end_索引
一次,然后我想返回计算
array
sum
以获得5的累积值,在这种情况下,新的
start_索引
将为4。第一个窗口:sum(array(1:5))=5;第二个窗口:sum(数组(4:6))=4(小于或等于5)这类似于没有固定长度的移动积分器窗口。只有结束索引在均匀地向前移动。当您更改
end\u index=6
时,您失去了我。为什么新的
开始索引=4
?累计差值
Summ(6)-Summ(3)=4
小于您的阈值,那么为什么我们要将
start\u index
更改为
4
而不是
3
?感谢您的帮助,Ian,我更改了数组和阈值以获得一个更简单的示例。在这种情况下,新的
start\u索引应为4。反向计算从索引6到4的总和将输出小于或等于5的4(新阈值)。这里的代码输出
start\u index
=3。您是在寻找最小的
start\u index
以便
sum(array(start\u index:end\u index))>=threshold
,还是最小的
sum(array(start\u index:end\u index))>=threshold
?[我仍然有点不清楚]由于这两个索引将彼此相邻,如果您要查找后者,您可以将一个添加到我输出的
end_index
。(
start\u index=end\u index+2-find(cumsum(fliplr(数组(1:end\u index)))>=threshold,1);
)rahnema1,这正是我要找的。非常感谢你。这里代码的
索引的输出将是:[
开始索引
结束索引
]=[1,5],[4,6],[4,9]等等。。。但是,我还想包括
end\u index
值为0时的索引,以便:[
start\u index
end\u index
]=[1,5]、[4,6]、[4,7]、[4,8]、[4,9]等。。。因为我还需要每个窗口的长度信息。这怎么可能呢?@BehnazEnsan你可能想要[1,2],[1,5][4,6]。。。因为第二个元素是0?如果可能,请为您的问题添加更多说明,并将您的预期输出添加到问题中[start_index,end_index]=[1,2]的窗口的累计总和不会为5。我想我希望它一直计算到超过5,然后在超过5之前保存索引。@BehnazEnsan感谢您接受了答案。但我不知道如何添加0的索引并排除[0,2]