是否有可能用 MATLAB 做一些像正则表达式这样的事情来过滤掉东西?基本上我正在寻找可以让我采用如下矢量的东西:
[1 2 1 1 1 2 1 3 3 3 3 1 1 4 4 4 1 1]
并将返回:
[3 3 3 3 4 4 4]
这些是不间断的序列(没有散布)。
这可能吗?
是否有可能用 MATLAB 做一些像正则表达式这样的事情来过滤掉东西?基本上我正在寻找可以让我采用如下矢量的东西:
[1 2 1 1 1 2 1 3 3 3 3 1 1 4 4 4 1 1]
并将返回:
[3 3 3 3 4 4 4]
这些是不间断的序列(没有散布)。
这可能吗?
使用 MATLAB 的内置regexp
函数进行正则表达式匹配。但是,您必须先将输入数组转换为字符串,然后才能将其提供给regexp
:
C = regexp(sprintf('%d ', x), '(.+ )(\1)+', 'match')
请注意,我用空格分隔值,以便也regexp
可以匹配多个数字。然后将结果转换回数值数组:
res = str2num([C{:}])
模式字符串中的点 ( .
) 表示任何字符。要仅查找某些数字的序列,请在括号 ( []
) 中指定它们。例如,仅查找 3 和 4 序列的模式是:
([34]+ )(\1)+
您可以通过使用以下方法检查相邻元素之间的相似性来过滤掉连续重复的值diff
:
res = x((diff([NaN; x(:)])' == 0) | (diff([x(:); NaN])' == 0))
或者,您可以只保留结果中的某些值,例如:
res(res == 3 | res == 4)
你可以这样做:
v=[1 2 1 1 1 2 1 3 3 3 3 1 1 4 4 4 1 1];
vals=unique(v); % find all unique values in the vector
mask=[]; % mask of values to retain
for i=1:length(vals)
indices=find(v==vals(i)); % find indices of each unique value
% if the maximum difference between indices containing
% a given value is 1, it is contiguous
% --> add this value to the mask
if max(indices(2:end)-indices(1:end-1))==1
mask=[mask vals(i)];
end
end
% filter out what's necessary
vproc=v(ismember(v,mask))
结果:
vproc =
3 3 3 3 4 4 4
这可能是另一种方法,尽管有点过于复杂。
如果你看到你的数组的图,你想保留它的水平集(即a == const
),它们是拓扑连接的(即由一件组成的)。
连贯地,这样的水平集正是对应于a==3
和的水平集a==4
。
这是一个可能的实现
a = [1 2 1 1 1 2 1 3 3 3 3 1 1 4 4 4 1 1]
r = []; % result
b = a; % b will contain the union of the level sets not parsed yet
while ~isempty(b)
m = a == b(1); % m is the current level set
connected = sum(diff([0 m 0]).^2) == 2; % a condition for being a connected set:
% the derivative must have 1 positive and 1
% negative jump
if connected == true % if the level set is connected we add it to the result
r = [r a(m)];
end
b = b(b~=b(1));
end
如果你尝试类似
a = [1 2 1 1 1 2 1 3 3 3 3 1 1 4 4 4 1 1] %initial vector
b = a>=3 %apply filter condition
a = a(b) %keep values that satisfy filter
a 将输出
a = [3 3 3 3 4 4 4]