How do I find no. of instances of each value till it changes?
Show older comments
I have the following input: [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
I want MATLAB to give me the number of 4s and 0s in each set till the digit changes. So I want my output to be: [6 3 6 8 5].
Thank you!
Answers (2)
Another option is using the code below.
input = [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
diff([0 find(diff(input)) numel(input)])
This can be achieved nicely with regular expressions. Capture a digit and backreference back to the same digits to find the patterns of consecutive numbers.
input = [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
num = regexp(char(input+'0'),'(\d)\1+','match');
n = cellfun(@numel, num)
>>n
6 3 6 8 5
6 Comments
Rik
on 18 Jul 2018
This is quite an expensive function, although this is masked if you don't suppress output. I didn't test Jan's submission, so that might be even faster.
input = [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
t1=0;t2=0;
for k=1:10000
tic
n=diff([0 find(diff(input)) numel(input)]);
t1=t1+toc;
tic
num = regexp(char(input+'0'),'(\d)\1+','match');
n=cellfun(@numel, num);
t2=t2+toc;
end
disp(t1)%0.0604 sec
disp(t2)%0.4362 sec
Paolo
on 18 Jul 2018
Yes you are right, your solution is a lot faster!
Paolo
on 18 Jul 2018
@Rik my solution can actually be improved to:
num = regexp(char(input+'0'),'(\d)\1+');
diff([num numel(input)+1])
Could you run the profiling again? I suspect your solution will still be faster, however I am curious. I know @cellfun can be expensive.
Rik
on 18 Jul 2018
You can run the code yourself as well, but here it is (on another pc now). Your second solution is indeed a bit faster (~25%).
input = [4 4 4 4 4 4 0 0 0 4 4 4 4 4 4 0 0 0 0 0 0 0 0 4 4 4 4 4];
t1=0;t2=0;t3=0;
for k=1:10000
tic
n=diff([0 find(diff(input)) numel(input)]);
t1=t1+toc;
tic
num = regexp(char(input+'0'),'(\d)\1+','match');
n=cellfun(@numel, num);
t2=t2+toc;
tic
num = regexp(char(input+'0'),'(\d)\1+');
n=diff([num numel(input)+1]);
t3=t3+toc;
end
disp(t1)%0.0298 sec
disp(t2)%0.2929 sec
disp(t3)%0.2220 sec
Paolo
on 18 Jul 2018
Cheers! Your solution is indeed very efficient. Reason as to why I asked you to do it is because I am on mobile and do not have pc access.
Rik
on 18 Jul 2018
It's a not-uncommon question, so I've seen some solutions before. My first instinct with the first I saw was a for-loop, so yours is miles better already.
And yeah, it's a bit much to copy this code to Matlab online or the app, just to have a benchmark, so I fully understand ;)
Categories
Find more on Data Type Conversion in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!