Using vectorization, how do I reduce a vector to only keep 1 instance of a repeating value (not sorted).

Hello,
I am trying to filter recorded data. I have a structure of all my DAQ channels, and each field is a channel. For each field, it is an array with the saved measurements. I want to plot the measurements, but not over time. I want to look at only when the value changes. My problem is that I want to make a smaller vector that just has the updated numbers in it, so that I can plot it later.
I'm not good with vectorization, but I don't think unique or diff can quite be used for this. Either way, I'm not very experienced with Matlab's functions (so what do I know?). I am assuming that this kind of task can be optimized by using some kind of logical indexing instead of a for loop.
For example:
cnt = [1;1;1;1;1;2;2;3;2;1;-1;....]
Updates = [1;2;3;2;1;-1;..]
I created the following code:
for i = 1: ChannelCount
DataName = (genvarname(char(ChannelNames{i,1})));
Data = strtRawChannel.(DataName);
DataLength = length(Data);
UpdateHolder(DataLength,1) = 0;
k = 1;
UpdateHolder(k) = Data(1);
for j = 1:(DataLength-1)
if ((Data(j+1)-Data(j))~=0)
k = k + 1;
UpdateHolder(k) = Data(j+1);
end
end
FilteredData.(DataName) = UpdateHolder(1:k);
end
Is there any hope to improving this code? It's not so bad for (300000,1), but I rather not be messy about this coding.
Thank you,
Kyle

 Respuesta aceptada

diff() can be used. The updates occur right after the positions for which diff() is non-zero.
idx = find(diff(cnt));
Updates = cnt([1 idx+1]);

2 comentarios

Because my measured data is in rows, (each column is one measured signal), I had to adjust your code:
Updates = cnt([1; idx+1]);
Also, I chose your code because on my trials, it ran nearly 2 times as fast as the code Azzi submitted. For reference, your code ran nearly 66 times as fast as my original code. Thank you, very much!
Thank you both for the help!
Sincerely, Kyle
I don't know how you did a test, I did not find the same speed
t1=0;t2=0;
cnt= randi(10,50000,1)
%----------code1----------------------
tic
for k=1:10000
idx = find(diff(cnt));
Updates = cnt([1 ;idx+1]);
end
t1=t1+toc;
%----------code2----------------------
tic
for k=1:10000
cnt(logical([1; diff(cnt)]));
end
t2=t2+toc;
Result
t1 =
19.5220
t2 =
14.2261

Iniciar sesión para comentar.

Categorías

Preguntada:

el 19 de En. de 2013

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by