将矢量值加起来直到阈值,然后重新开始
Sum up vector values till threshold, then start again
我有一个向量 a = [1 3 4 2 1 5 6 3 2]
。现在我想用 a
的 cumsum
创建一个新向量 'b',但是在达到阈值后,比方说 5,cumsum
应该重置并重新开始,直到达到阈值,所以新向量应该是这样的:
b = [1 4 4 2 3 5 6 3 5]
有什么想法吗?
计算累计和并替换符合您条件的索引值。
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) ;
一种方法是使用循环。您创建第一个累积和 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
通过规范化 cumsum
with the threshold and flooring you can get grouping indizes for accumarray
的参数,然后可以cumsum
ming groupwise:
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{:}]
您可以构建一个稀疏矩阵,当它乘以原始向量时,returns 就是累积和。我没有将此解决方案与其他解决方案进行计时,但我强烈怀疑这将是大型 a 数组中最快的。
% 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.';
我有一个向量 a = [1 3 4 2 1 5 6 3 2]
。现在我想用 a
的 cumsum
创建一个新向量 'b',但是在达到阈值后,比方说 5,cumsum
应该重置并重新开始,直到达到阈值,所以新向量应该是这样的:
b = [1 4 4 2 3 5 6 3 5]
有什么想法吗?
计算累计和并替换符合您条件的索引值。
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) ;
一种方法是使用循环。您创建第一个累积和 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
通过规范化 cumsum
with the threshold and flooring you can get grouping indizes for accumarray
的参数,然后可以cumsum
ming groupwise:
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{:}]
您可以构建一个稀疏矩阵,当它乘以原始向量时,returns 就是累积和。我没有将此解决方案与其他解决方案进行计时,但我强烈怀疑这将是大型 a 数组中最快的。
% 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.';