1
votes

I have a Matlab time series data set, which consist of a signal that can only be 1 or 0. How can I get rid of all the values except for the changing ones? For example:

1
1
1
0
1
0
0
0

should ideally result in

1
0
1
0

while keeping the correct time values as well of course. Thing is, that I need to find the frequency of the signal. The time should be measured from 0->1 to the next time 0->1 occurs. The smallest time / highest frequency is what I need in the end.

Thanks!

3
When reading your question I assumed you have a timeseries object, the other two answers assume your input data is a vector. What is right?Daniel
You are right. I am getting a timeseries object out of a simulink simulation. I tried to use the diff methods described below by you guys but so far couldn't get it to work. I'll try the getsamples method next :)Jonnnny

3 Answers

4
votes

You can use the getsamples method to get a time series which contains a subset of the original samples. Remains to identify the indices where the time series has changed, for this purpose you can use diff and logical indexing:

ts = timeseries([1 1 1 0 1 0 0 0],1:8)
ts.getsamples([true;squeeze(diff(ts.Data)) ~= 0])
3
votes

A simple and clever call to to diff should be sufficient:

>> A = [1; 1; 1; 0; 1; 0; 0; 0];
>> B = A(diff([-Inf; A]) ~= 0)

B =

     1
     0
     1
     0

The code is quite simple. diff finds pairs of differences in an array. Concretely, given an array A, the output is of the following structure:

B = [A(2) - A(1), A(3) - A(2), ..., A(N) - A(N-1)];

N is the total length of the signal. This results in a N-1 length signal. As such, a trick that you can use is to append the array A with -Inf (or some high non-zero value) so that when you find the difference between the first element of this appended array and the actual first element of the true array, you will get some non-zero change. That is registered with diff([-Inf; A]). The next thing you'll want is to check is to see where the differences are non-zero. Whenever there is a non-zero difference, that is a position that you want to keep because there has been a change that occurred. This produces a logical array and so the last step is to use this to index into your array A and thus get the result.


This only extracts out the signal you need however. If you'd like to extract the time in between unique elements, supposing you had some time vector t that was as long as your signal stored in A. You would first record the logical vector in a separate variable, then index into both your time array and the signal array to extract out what you need (original idea from user dfri):

ind = diff([-Inf; A]) ~= 0;
times = t(ind);
B = A(ind);
2
votes

You can make use of diff and logical to save the results as a logical array, used as a subsequent index filter in your data (say t for time and y for boolean values ))

%// example
t = 0:0.01:0.07;
y = [1,1,1,0,1,0,0,0];

%// find indices to keep
keep = [true logical(diff(y))];

%// truncated data
tTrunc = t(keep)
yTrunc = y(keep)

with the results for the example as follows

tTrunc =

     0     0.0300    0.0400    0.0500


yTrunc =

     1     0     1     0