将矢量值相加到阈值,然后重新开始

时间:2017-06-08 12:37:34

标签: arrays matlab cumsum

我有一个向量a = [1 3 4 2 1 5 6 3 2]。现在我想创建一个新的向量' b'使用cumsum a,但是在达到阈值后,让我们说5,cumsum应该重置并重新开始直到它再次达到阈值,所以新的向量应该看起来像这样:

b = [1 4 4 2 3 5 6 3 5]

有什么想法吗?

4 个答案:

答案 0 :(得分:2)

您可以构建一个稀疏矩阵,当乘以原始向量时,返回累积总和。我还没有把这个解决方案与其他解决方案进行对比,但我强烈怀疑这对于大型阵列来说是最快的。

% Original data
a = [1 3 4 2 1 5 6 3 2];
% Threshold
th = 5;
% Cumulative sum corrected by threshold
b = cumsum(a)/th;
% Group indices to be summed by checking for equality,
% rounded down, between each cumsum value and its next value. We add one to
% prevent NaNs from occuring in the next step. 
c = cumsum(floor(b) ~= floor([0,b(1:end-1)]))+1;
% Build the sparse matrix, remove all values that are in the upper
% triangle.
S = tril(sparse(c.'./c == 1));
% In case you use matlab 2016a or older:
% S = tril(sparse(bsxfun(@rdivide,c.',c) == 1));
% Matrix multiplication to create o.
o = S*a.';

答案 1 :(得分:1)

通过将cumsum的参数标准化为阈值和地板,您可以对accumarray进行分组,然后可以按cumsum组进行分组:

t = 5;
a = [1 3 4 2 1 5 6 3 2];

%// cumulative sum of normalized vector a 
n = cumsum(a/t);
%// subs for accumarray
subs = floor( n ) + 1;
%// cumsum of every group
aout = accumarray( subs(:), (1:numel(subs)).', [], @(x) {cumsum(a(x))});
%// gather results;
b = [aout{:}]

答案 2 :(得分:0)

一种方法是使用循环。您创建了第一个累积总和cs,然后只要cs中的元素大于您的阈值th,就可以使用其余元素的累积总和中的元素替换它们在a

由于a中的某些元素可能大于th,因此除非我们也消除这些元素,否则此循环将是无限的。

这是一个带有while循环的简单解决方案:

a = [1 3 4 2 1 5 6 3 2];
th = 5;
cs = cumsum(a);
while any(cs>th & cs~=a) % if 'cs' has values larger that 'th',
                       % and there are any values smaller than th left in 'a'
    % sum all the values in 'a' that are after 'cs' reached 'th',
    % excluding values that are larger then 'th'
    cs(cs>th & cs~=a) = cumsum(a(cs>th & cs~=a));
end

答案 3 :(得分:-1)

计算累积总和并替换符合您条件的指数值。

 a = [1 3 4 2 1 5 6 3 2] ;

 b = [1 4 4 2 3 5 6 3 5] ;

 iwant = a ;
 a_sum = cumsum(a) ;
 iwant(a_sum<5) = a_sum(a_sum<5) ;