Reputation: 52247
In Matlab I have a vectors that looks like this:
0 0 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 1 0 1
What I want to do now is to count the number of 1 in this vector. Consecutive 1s count as 1. Additionally, I want also to calculate the average and median numbers of 0s between 1s. So for this example:
1s: 5
Median 0s: 3.5
Average 0s: 3
I solved that with a brute force method, that is investigate each element in a loop and check the previous as well as the next element. But I'm sure there has to be a solution that is way faster. Any idea?
Upvotes: 2
Views: 4176
Reputation: 112779
Given the data in vector v
,
v = [ 0 0 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 1 0 1 ]; % data
compute as follows:
w = [ 1 v 1 ]; % auxiliary vector
runs_zeros = find(diff(w)==1)-find(diff(w)==-1); % lenghts of runs of 0's
% Desired results:
number_ones = length(runs_zeros)-1+v(1)+v(end);
% For average and median, don't count first run if v(1) is 0,
% or last run if v(end) is 0:
average_runs_zeros = mean(runs_zeros(2-v(1):end-1+v(end)));
median_runs_zeros = median(runs_zeros(2-v(1):end-1+v(end)));
This is faster than @TryHard's solution because it doesn't require converting to strings
Upvotes: 4
Reputation: 5073
You can do it as follows:
dat=[0 0 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 1 0 1];
str = regexprep(num2str(dat),' ','');
[n1 istart1 iend1] = regexp(str,'[1]+','match','start','end');
[n0 istart0 iend0] = regexp(str(min(istart1):max(iend1)),'[0]+','match','start','end');
% number of strings of `1`s
length(n1)
% property of intercalated strings of `0`s
median([iend0-istart0+1])
mean([iend0-istart0+1])
Upvotes: 0
Reputation: 47854
Okay, so this seems to be working
>> a=[0 0 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 1 0 1];
>> %Remove traling and leading zeros
>> y = a(find(a,1,'first'):find(a,1,'last'));
>> q = diff([0 a 0] == 1);
>> v = find(q == -1) - find(q == 1);
>> length(v) % Consecutive Ones
ans =
5
>> q = diff([0 ~y 0] == 1);
>> v = find(q == -1) - find(q == 1);
>> v
v =
3 4 4 1
>> median(v)
ans =
3.5000
>> mean(v)
ans =
3
Upvotes: 1