我有一个向量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]
有什么想法吗?
答案 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) ;