除去那些侧翼非零值以外的所有零值

Ann*_*ann 2 arrays matlab vector

给出一个向量:

a = [0;0;2;3;0;2;10;11;0;0;0;4;5;8;0;0;0]
Run Code Online (Sandbox Code Playgroud)

任何人都可以显示或建议一种方法来删除所有零值,除了那些侧面非零值的零值?

以上所需的结果将是:

b = [0;2;3;0;2;10;11;0;0;4;5;8;0]
Run Code Online (Sandbox Code Playgroud)

删除这些值的地方:

[ 0 ; 0; 2; 3; 0; 2; 10; 11; 0; 0 ; 0; 4; 5; 8; 0; 0 ; 0 ]

我不知道从哪里开始这个问题而不必使用一组IF语句,例如:

for k=1:length(a)
    if a(k) == 0 && a(k+1) == 0
        *delete value*
    end
    if a(k) == 0 && a(k+1) >0
        *keep/store value*
    end
    if a(k) > 0
        *keep/store value*
    end
    if a(k) == 0 && a(k-1) >0
        *keep/store value*
    end
end
Run Code Online (Sandbox Code Playgroud)

等等.

Lui*_*ndo 6

你可以使用卷积:

b = a(conv(abs(sign(a)), ones(3,1), 'same')>0);
Run Code Online (Sandbox Code Playgroud)

其工作原理如下:

  1. 转换a为零或一(abs(sign(a)))的向量,如果条目a为零,则为零,否则为1.
  2. 卷入三个(conv(..., ones(3,1), 'same'))的面具.因此,非零值a会在其位置和相邻位置产生非零结果.
  3. 将其与零进行比较以创建a索引(a(...>0))的逻辑向量.

这可以很容易地推广更远的邻居.具体来说,使用掩码ones(2*N+1,1)保持零值不N超过非零值的条目.


Dev*_*-iL 6

我有另一个想法(授予,与其他两个没有很大不同),使用逻辑索引:

a(~(~a & ~[diff(a);0] & ~[0;diff(a)] ));
Run Code Online (Sandbox Code Playgroud)

说明:

  • ~- boolean not,返回表示输入"反向"的布尔值.
  • ~a- 返回零元素a(在您给出的示例中不需要,但如果您想要保留重复的非零值,则很重要).
  • ~[diff(a);0] & ~[0;diff(a)] - 返回任何大小的导数为零的值.
  • a(~(...))- 返回的值a不是"两侧具有相同值的零",即b.

写同样事物的另一种方式(使用De Morgan的定律并利用非零值的"真实性"):

a( a | [diff(a);0] | [0;diff(a)] );
Run Code Online (Sandbox Code Playgroud)

您可以将其视为" 保留哪些值 "而不是" 删除哪些值 ",其中我可以想到的最简单的方法来定义要保留的值是"所有非零元素零元素都具有非零值侧".