【问题标题】:cumsum of values for same timeunit同一时间单位的值的累积
【发布时间】:2014-07-28 13:30:09
【问题描述】:

我有以下向量:

A=[1 0 1 0 0 1 0 1 0 0];
B=[1 2 3 4 5 6 7 8 9 10];

在这种情况下,A 表示一个时间向量,其中 1 表示一个时间单位的开始。 现在我想将 B 中与具有相同长度的 3 步的时间单位相对应的所有值相加。 所以在这个例子中,这意味着 B 的第 3、第 4 和第 5 个值以及第 8、第 9 和第 10 个值应该相加,因为它们的时间单位长度为 3。

B_result=[12 27];

我知道 cumsum() 是执行此操作的命令,但我不知道如何说只有取决于 A 的时间索引的这些特定值应该被求和。

你能帮帮我吗?

非常感谢

【问题讨论】:

    标签: matlab cumsum


    【解决方案1】:

    您可以将cumsum 与accumarray 和hist 一起使用:

    csa = cumsum(A); %// from begining og unit to unit indices
    n = hist(csa, 1:max(csa));  %// count num of steps in each unit
    B_result = accumarray( csa', B' ); %// accumulate B into different time units
    B_result(n~=3) = []; %// discard all time units that do not have 3 steps
    

    【讨论】:

    • 我在使用 accumarray 时遇到错误:第二个输入 VAL 必须是一个向量,SUBS 中的每一行都有一个元素,或者是一个标量。我不明白?
    • @user3858157 您可能只需将输入转置 (.') 到列 - 不需要 reshape。
    【解决方案2】:

    对于更简单的模式匹配,可以使用strfind:

    loc = strfind([A,1],[1 0 0 1]); %// add the 1 at the end of A and the pattern to avoid longer intervals
    idx = bsxfun(@plus,loc,(0:2)'); %'// get the indices that need to be summed
    
    result = sum(B(idx),1); %// obtain the result
    

    【讨论】:

    • @LuisMendo:regexp 不做双打,但是是的,如果你先转换为字符串,你可能会用 regexprep 制作一个“漂亮”的例子......
    • @LuisMendo:好的,也删除了我的其他评论。顺便说一句:regexprep(char(A+'0'),'10{2}','\b\b${num2str(sum(B(length($)+(1:3))))} ')` 使用给定的输入返回正确的结果,但您不能将其转换为数字结果 ;)
    • 你能检查一下吗?它在 Matlab 2010b 中给了我一个错误,但可能是它的版本太旧了
    • @LuisMendo:美元符号后面有一个刻度线,被标记语言吞噬。试试这个: regexprep(char(A+'0'),'10{2}','\b\b${num2str(sum(B(length($`)+(1:3))))} ')
    • 不过,有可能是正则表达式中的命令表达式的某些功能已在以后添加。
    【解决方案3】:
    N = 3; %// We want to detect a one followed by exactly N-1 zeros. Call that
    %// sequence an "interesting part"
    ind = find([A 1]); %// find ones. Append a last one to detect a possible 
    %// interesting part at the end.
    ind = ind(diff(ind)==N); %// index of beginning of interesting parts
    cs = cumsum(B); %// accumulate values
    B_result = cs(ind+N-1)-cs(ind-1); %// use index to build result
    

    【讨论】:

    • @Shai 谢谢。我添加了一些 cmets
    【解决方案4】:

    Jonas' Idea 的更通用应用:

    A = [1 0 1 0 0 1 0 1 0 0 0 0 1];
    B = [1 2 3 4 5 6 7 8 9 10 11 12];
    
    n = 3;
    
    result = arrayfun(@(x) sum( B(x:x+n-1) ), strfind([A,1],num2str(10^n+1)-48)) 
    

    或者使用cumsum而不是sum,我不确定你真正想要什么:

    result = arrayfun(@(x)  cumsum( B(x:x+n-1) ), ...
                           strfind( [A,1],num2str(10^n+1)-48 ) ,'uni',0) 
    
    %optional:
    result = cell2mat(result')
    

    【讨论】:

    • cumsum 的第二个解决方案对我有用。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 2014-07-12
    相关资源
    最近更新 更多