从Matlab数组中选择所有的'77'区间

4

我有一个数据数组,但是这些数据被77个间隔所分割(这些间隔的长度不同),就像这样:

[-1, 2, 2, 4, -5, 77, 77, 77, 6, 5, 34, 77, 77, 4, 7...]

找到这个区间的任何起始或结束索引都不是问题,但我需要以某种方式保存它们的索引(?),数组(我想)对此不好处理(但也许有解决方法。写在矩阵中?但结果维度不同..

[-1, 2, 2, 4, -5, 77, 77, 77, 6, 5, 34, 77, 77, 4, 7...]

预计会得到一个答案。
[6,7,8]
[12,13]

索引从1开始。我该怎么做?


1
请您再详细解释一下您想要实现什么?如果您需要删除数据中所有匹配 77 的元素的索引,可以使用 A(A==77)=[] 来代替。其中 A 是您的数据向量。如果您想要找到所有索引并将它们存储在一个单独的向量中,可以使用 find(A==77) 来完成这个操作,这将会给您一个包含索引的单一向量 [6,7,8,12,13] - user1884905
使用单元数组来存储你的结果。这样,每个单元条目中可以有不同数量的索引。 - Shai
user1884905,我需要一些数组,它们的数量等于每个间隔包含的元素的索引数/Shai,感谢您的帮助-我会尝试找到有关单元数组的信息并实现它。 - curiousity
3个回答

2

您可以使用diff来检测每个运行的开始和结束,然后使用arrayfun创建连续索引的单元数组:

data = [-1, 2, 2, 4, -5, 77, 77, 77, 6, 5, 34, 77, 77, 4, 7]; %// example data

aux = diff(data==77); %// add dummy value at end, in case final data is 77
starts = find(aux==1)+1;
if data(1)==77 %// special case: start with a run
    starts = [1 starts];
end
ends = find(aux==-1);
if data(end)==77  %// special case: end with a run
    ends = [ends numel(data)];
end
result = arrayfun(@(n) starts(n):ends(n), 1:length(starts), 'uni', false);

使用示例数据,得到以下结果:

>> result{1}

ans =

     6     7     8

>> result{2}

ans =

    12    13

结果 = arrayfun(@(n) starts(n):ends(n), 1:length(starts)-1, 'uni', false); - curiousity
@curiousity 为什么是“-1”?这样你就会失去最后一次运行。 - Luis Mendo
尝试访问ends(310);索引越界,因为numel(ends)= 310。如果-1,则此解决方案对应于use1884905结果。 - curiousity
抱歉,已更正。请现在尝试。 - Luis Mendo
除了Matlab自身的帮助文档,我不知道其他太多的参考资料。但这可能是一个不错的参考:http://www.mathworks.es/es/help/matlab/cell-arrays.html Loren的博客也很有名,她在这里可能会解释一些好东西http://blogs.mathworks.com/loren/2006/06/21/cell-arrays-and-their-contents/ 免责声明:我实际上没有阅读过这些参考资料 :-) - Luis Mendo
显示剩余2条评论

1

如果它是

[6,8]
[12,13]

您想要的是:
答案是:
m=[-1, 2, 2, 4, -5, 77, 77, 77, 6, 5, 34, 77, 77, 4, 7]
r=[find([1,m]~=77&[m,1]==77);find([m,1]~=77&[1,m]==77)-1]'

而要获得您所要求的内容:

for bounds=[find([1,m]~=77&[m,1]==77);find([m,1]~=77&[1,m]==77)-1];
  disp(bounds(1):bounds(2))
end

如果你想测试负数而不是77,请将~=77替换为>=0,将==77替换为<0。


disp([find([1,m]=77&[m,1]==77);find([m,1]=77&[1,m]==77)-1]') 现在显示: 6 8 12 13 - user2987828
这很不错,但我需要这些答案作为向量(以了解有多少这样的间隔)。该死,在C#中没有这样的问题 - 可以保存任何您想要的对象。 - curiousity
@curiosity是不是要求[6,7,8]而不仅仅是[6 8]?问题中指定了77的行长度不同。或者我错了吗,@curiosity? - Stewie Griffin
@curiousity 我认为解决方案是你最好的选择(在我看来比你要求的更好)。你可以按如下方式查看这样的间隔数量(我假设你将此解决方案存储在向量I中):size(I,1)。并且你可以通过diff(I') + 1来告诉每个范围内有多少个77。 - Dan
是的,Robert P,你说得对。实际上,我正在搜索该数组中的负值,并尝试将它们存储到向量中,就像我上面描述的那样,但我决定不要在问题上过载 - 所以写77 - 也许这里不对。但是,Dan,我不知道每个向量中有多少元素。这个问题很简单 - 子集切割,但在matlab中并不简单。 - curiousity

1
这里是实现你所需功能的一种方法。最终索引被收集在一个单元格F中。我已经把所有的输出都放在注释中,这样你就可以逐步执行它,但我会简要解释一下我正在做的事情,因为它是相当丑陋的解决方案。
使用向量A存储数据,首先使用find()找到所有匹配77的索引。然后,我想在两个连续索引之间的差大于1的位置处切割该向量。我想使用mat2cell()将向量转换为单元格,所以我再次使用diff()获取所有长度。
A = [-1, 2, 2, 4, -5, 77, 77, 77, 6, 5, 34, 77, 77, 4, 7];
B = find(A==77);             %// B = [6  7  8  12  13]
C = diff(B);                 %// C = [1  1  4  1]
D = find(C~=1);              %// D = [3]
E = diff([0 D length(B)]);   %// E = [3  2]
F = mat2cell(B,1,E);         %// F = [1x3 double] [1x2 double]

%// F{1} = [6   7   8]
%// F{2} = [12 13]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接