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

时间:2016-08-03 09:05:51

标签: arrays matlab vector

给出一个矢量:

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

任何人都可以显示或建议删除所有零值的方法,除非是那些非零值的方法吗?

上述所需的结果将是:

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

删除这些值的地方:

[ 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

等等。

3 个答案:

答案 0 :(得分:6)

您可以使用convolution

b = a(conv(abs(sign(a)), ones(3,1), 'same')>0);

其工作原理如下:

  1. a转换为0或1(abs(sign(a)))的向量,如果a的条目为零,则为零,否则为0。
  2. 使用三个掩码(conv(..., ones(3,1), 'same'))进行卷积。因此a中的非零值会在其位置和相邻位置产生非零结果。
  3. 将其与零进行比较,以创建一个用a编入索引的逻辑向量(a(...>0))。
  4. 这可以轻松概括以保持更远的邻居。具体来说,使用掩码ones(2*N+1,1)来保持零值不超过非零值的N条目。

答案 1 :(得分:6)

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

a(~(~a & ~[diff(a);0] & ~[0;diff(a)] ));

说明:

  • ~ - 布尔not,返回一个布尔值,表示"对面"输入。
  • ~a - 返回a的零元素(在您给出的示例中不需要它,但如果您想要保留重复的非零值,则非常重要。)
  • ~[diff(a);0] & ~[0;diff(a)] - 返回任意大小的派生值为零的值。
  • a(~(...)) - 返回a的值,这些值不是'零,并且两边都是相同的值",即b

编写相同内容的另一种方法(使用De Morgan's laws并利用非零值的"真实性")

a( a | [diff(a);0] | [0;diff(a)] );

您可以将其视为发现" ,其值为保持 "而不是" 哪些值为删除 ",其中我能想到的最简单的方法来定义要保留的值是"所有非零元素零元素,任何一方都有非零"。

答案 2 :(得分:4)

如果你创建了两个额外的向量,一个向左移动,一个向右移动向量a编辑:使用circshift,如下面的评论所示):

a       = [0;0;2;3;0;2;10;11;0;0;0;4;5;8;0;0;0];
a_right = circshift(a,-1);
a_left  = circshift(a,1);

创建矩阵M:

M = [a,a_right,a_left];

并总结每一行:

s = sum(M,2);

然后找到与0不同的组件:

i = find(s~=0);

这将为您提供从初始矢量中选择的正确索引:

b=a(i)

我明白了:

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