matlab fxn:在struct数组中找到连续的区域和返回边界

joh*_*hen 2 matlab

对于那里的matlab大师来说这是半个问题和半个挑战:我想让一个函数接受逻辑数组(false/true)并给出包含trues的所有连续区域的开头和结尾struct数组.
像这样的东西:

b = getBounds([1 0 0 1 1 1 0 0 0 1 1 0 0])
Run Code Online (Sandbox Code Playgroud)

应该回来

b = 3x1 struct array with fields:  
beg   
end
Run Code Online (Sandbox Code Playgroud)

>> b(2)

ans = 

   beg: 4

   end: 6
Run Code Online (Sandbox Code Playgroud)

我已经有了一个实现,但我真的不知道如何处理struct数组,所以我想问你怎么做 - 我必须通过mat2cell处理,当我必须处理更大的struct时数组变得很麻烦.我看起来像这样:

df = diff([0 foo 0]);

a = find(df==1); l = numel(a); 
a = mat2cell(a',ones(1,l)) 
[s(1:l).beg] = deal(a{:});

b = (find(df==-1)-1); 
b = mat2cell(b',ones(1,l)) 
[s(1:l).end] = deal(b{:});
Run Code Online (Sandbox Code Playgroud)

小智 7

我不明白你为什么要使用mat2cell等.你犯的问题太多了.

给定布尔行向量V,找到序列中所有1组的起点和终点.

V = [1 0 0 1 1 1 0 0 0 1 1 0 0];
Run Code Online (Sandbox Code Playgroud)

你可以从差异中获得大部分.从而

D = diff(V);
b.beg = 1 + find(D == 1);
Run Code Online (Sandbox Code Playgroud)

这将定位所有组的开始点,除了可能是第一组.所以添加一个简单的测试.

if V(1)
  b.beg = [1,b.beg];
end
Run Code Online (Sandbox Code Playgroud)

同样,每组都必须在另一组开始之前结束.所以只需找到终点,再次担心最后一组是否会被遗漏.

b.end = find(D == -1);
if V(end)
  b.end(end+1) = numel(V);
end
Run Code Online (Sandbox Code Playgroud)

结果如我们所料.

b
b = 
    beg: [1 4 10]
    end: [1 6 11]
Run Code Online (Sandbox Code Playgroud)

事实上,我们可以更轻松地完成所有这些工作.一个简单的解决方案是在我们执行diff之前始终将零附加到V的开头和结尾.看看它是如何工作的.

D = diff([0,V,0]);
b.beg = find(D == 1);
b.end = find(D == -1) - 1;
Run Code Online (Sandbox Code Playgroud)

同样,结果如预期.

b
b = 
    beg: [1 4 10]
    end: [1 6 11]
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我可能会避免在这里使用end,即使是作为结构字段名称.使用matlab关键字作为变量名称进入是一个坏习惯,即使它们只是字段名称.

  • 一方面注意......如果你想创建一个*数组结构*而不是*一个结构存储数组*,你可以这样做:`b = struct('beg',num2cell(find(D == 1)) ,'end',num2cell(find(D == -1)-1));` (3认同)