在MATLAB中使用ismember查找数组位置的快速替代方法

时间:2017-10-17 13:16:28

标签: matlab sorting signal-processing

我有一个数组A.

 A = [1 0 1 4.3 4.5 5 4.3 3 0 0 0 2 6.2 6.3 7 6.2 7.4 8  7.2 1 2 3 4 2];

正面和负面局部最大值和最小值。

Ypos =[  5     7     8     4]
Yposloc = [6    15    18    23  ]
Yneg   = [     0         0    6.2000    1.0000 ]
Ynegloc = [2     9    16    20 ]

现在我将所有最大值和最小值组合在一个数组中

Y = [0    5.0000         0    7.0000    6.2000    8.0000    1.0000    4.0000]
Yloc = [2     6     9  13  15    18    20    23]

然后我应用了滤镜并删除了一些最大值和最小值,并将已移除位置的局部最大值和最小值分开

Ylocknew = [0    5.0000         0    7.0000       8.0000    1.0000    4.0000]
Yloc = [2     6     9    15    18    20    23]

或者只是有办法找出原始数组中这些过滤值的位置。

在分离局部最大值和最小值后,我得到了这些数组

Yposnew = [    5     7     8     4]
Ynegnew = [   0     0     1]

问题。

我需要问一下,有没有快速的方法可以在原始数组Yposnew中找到YnegnewA的位置而不是循环,因为循环占用了大量时间。

(请注意,在我的原始数据中,我有重复的元素,所以我需要这些元素。)

请查看代码。

 A = [1 0 1 4.3 4.5 5 4.3 3 0 0 0 2 6.2 6.3 7 6.2 7.4 8  7.2 1 2 3 4 2];
 t= 1:numel(A);
 X=A;
[Ypos,Yposloc] = findpeaks(X);
[Yneg,Ynegloc] = findpeaks(-X);
Yneg = -1*Yneg;
Y = zeros(1, max([Yposloc, Ynegloc]));
Yloc = zeros(size(Y));
Yloc(Yposloc) = Yposloc;
Yloc(Ynegloc) = Ynegloc;
Y(Yposloc) = Ypos; 
Y(Ynegloc) = Yneg;

Y = Y(Yloc ~= 0) % this is the combined signal what I am expecting
Yloc = Yloc(Yloc ~= 0) % this is the combined locations what i am expecting

% I have applied limits on combined local maxima and minima array 

for i = 1:numel(Y)-1
%     if  (Y(i+1)<=-6 && Y(i+1)>=8)
    if  (Y(i+1)>= (Y(i)-1) && Y(i+1)<=(Y(i)+1))
%             if  (Y(i+1)<=-1 || Y(i+1)>=1)
    Y(i+1)= inf;

  else 
    Y(i)= Y(i);
  end
%      i=i+1;
  end
 Ylocknew = Y;

 % I have calculated Filtered locations for filtered local maximas array
 for b = 1:numel(Yloc)
 if (Ylocknew(1,b) == inf)
    Yloc(1,b) = inf;
else
    Yloc(1,b) = Yloc(1,b);


end
  b=b+1;

end

 Yloc(Yloc==inf)= []
 Ylocknew(Ylocknew==inf)= []


% I have separated positive and negative local maximas from limited array 

[Yposnew] = Ypos(ismember(Ypos, Ylocknew ));
[Ynegnew] = Yneg(ismember(Yneg, Ylocknew ));

需要快速替代或快速方式来计算原始数组中过滤的局部最大值和最小值的位置。

% Filtered Locations for FIltered positive local maximas

 for c = 1:numel(Yposnew)
     if (Yposnew(c) == X(Yposloc(c)))
         Yposlocfiltered(c)= Yposloc(c);
     elseif (Yposnew(c) ~= X(Yposloc(c)))
         d=c;
         while(Yposnew(c) ~= X(Yposloc(d)))
               d= c+1;             
         end
              Yposlocfiltered(c)= Yposloc(d);
     end
 end

  % Filtered Locations for Filtered negative local maximas

  for r = 1:numel(Ynegnew)
     if (Ynegnew(r) == X(Ynegloc(r)))
         Yneglocfiltered(r)= Ynegloc(r);
     elseif (Ynegnew(r) ~= X(Ynegloc(r)))
         s=r;
         while(Ynegnew(r) ~= X(Ynegloc(s)))
               s= r+1;             
         end
              Yneglocfiltered(r)= Ynegloc(s);
     end
 end

1 个答案:

答案 0 :(得分:1)

如果您退后一步,查看您从ismember的中间结果中获得的信息,您已经获得了正确位置的索引:

ismember行之前的变量值:

Ypos =[5 7 8 4]
Yposloc = [6 15 18 23]
Yneg = [0 0 6.2000 1.0000]
Ynegloc = [2 9 16 20]
Ylocknew = [0 5.0000 0 7.0000 8.0000 1.0000 4.0000]
Yloc = [2 6 9 15 18 20 23]

现在,我们可以保存并使用它们两次,而不是使用ismember返回的逻辑索引然后将它们丢弃,我们可以保存它们并使用它们两次:

posidx = ismember(Ypos, Ylocknew);   % get locations of Ylocknew in Ypos
% posidx = [1  1  1  1]; keep all Ypos values
Yposnew = Ypos(posidx);         % save the values...
Yposlocnew = Yposloc(posidx);   % and save their corresponding locations

negidx = ismember(Yneg, Ylocknew);   % repeat for Yneg
% negidx = [1  1  0  1]; we've removed Yneg(3)
Ynegnew = Yneg(negidx);              % saving values...
Yneglocnew = Ynegloc(negidx);        % and locations

结果:

Yposnew = [5 7 8 4]
Yposlocnew = [6 15 18 23]
Ynegnew = [0 0 1]
Yneglocnew = [2 9 20]