【问题标题】:MATLAB: check whether next n entries of vector are less than certain valueMATLAB:检查向量的下 n 个条目是否小于某个值
【发布时间】:2026-01-28 19:40:02
【问题描述】:

我正在处理一个包含多个正弦函数线性组合值的大向量(其中第一个条目是在 0 毫秒的时间,第 n 个条目是在第 n 毫秒)。现在我想提取包含(相同组合)正弦函数的向量片段,并将它们分别存储。

因此我想检查彼此相邻的 5 个条目是否为零,这意味着这将是两个单独的线性组合之间的“切割”。如果有 5 个或更多条目彼此相邻且等于 0,则应在此处进行剪切。例如以下(短)向量。

vector = [ 0 0 0 0 0 0 0 8 9 1 0 0 3 2 0 0 0 0 0 6 6 2 0 0 0 1 ]应该被分割成两个独立的向量,即 vec1= [8 9 1 0 0 3 2]vec2= [6 6 2 0 0 0 1]

我想我可以使用内置的find 函数,但我认为它不能查找“至少”5 个彼此相邻且等于 0 的条目,对吗?

【问题讨论】:

    标签: matlab vector find


    【解决方案1】:

    从你的例子开始......

    v = [ 0 0 0 0 0 0 0 8 9 1 0 0 3 2 0 0 0 0 0 6 6 2 0 0 0 1 ];
    

    我们可以做到以下几点:

    % 1. Create an index `idx` which groups elements either as zeros or non-zeros, 
    %    with an increasing group number for each subsequent set
    idx = cumsum( [1, diff(v==0) ~= 0] );
    % = [ 1 1 1 1 1 1 1 2 2 2 3 3 4 4 5 5 5 5 5 6 6 6 7 7 7 8 ];
    
    % 2. Split by this group, regardless of what's in it
    grps = splitapply( @(x){x}, v, idx );
    % = { {1×7 double}, {1×3 double}, {1×2 double}, {1×2 double}, {1×5 double}, ... }
    
    % 3. Get the indices for groups, incremented when the 5-zeros condition is met
    zIdx = cellfun( @(x) x(1) == 0, grps ); % Just alternating 0/1, as groups alternate
    idx = cellfun( @numel, grps ) >= 5 & zIdx;
    idx = cumsum( idx ) .* ~idx;
    % = [ 0 1 1 1 0 2 2 2 ]
    
    % 4. Group everything together
    out = arrayfun( @(x) [grps{idx==x}], 1:max(idx), 'uni', 0 );
    % { [8 9 1 0 0 3 2], [6 6 2 0 0 0 1] }
    

    我不确定这是否比编写循环更快...

    【讨论】:

      【解决方案2】:

      您可以将regexpsplit 选项一起使用:

      v   = [0 0 0 0 0 0 0 8 90 0 0 0 0 1 0 0 3 2 0 0 0 0 0 6 6 2 0 0 0 1 ];
      %     vector to string then extract the subvector
      r   = regexp(num2str(v),'(?<![0-9])(0\s+){5,}','split')
      %     string to vector
      out = cellfun(@str2num,r,'UniformOutput',0)
      

      使用这个正则表达式:(?&lt;![1-9])(0\s+){5,}

      (?&lt;![0-9]) :检查零之前没有数字,因此90 0 0 0 0 不应拆分向量。

      (0\s+){5,} :检查至少 5 个连续的 0。

      【讨论】:

      • 当我运行这段代码时,rout 都是一个 1x1 单元格数组,因此不会被剪切。我认为拆分不会像它应该的那样工作。你得到不同的结果?
      • 是的,确实,正则表达式中有错字。现在应该没问题了。