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

 채택된 답변

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

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

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Resizing and Reshaping Matrices에 대해 자세히 알아보기

질문:

2013년 1월 19일

Community Treasure Hunt

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

Start Hunting!

Translated by