Suppose I have a vector:
x = [1 1 1 1 2 2 2 8 8 8 8 8 8 0 0 9 9 7 5 5 2 2 2 2 2]
I want to obtain:
b = [1 2 3 4 1 2 3 1 2 3 4 5 6 1 2 1 2 1 1 2 1 2 3 4 5]
Basically each block of integer is replaced by continuous index of the count.
Solution:
Some initial processing to detect block size and locations:
y = find([true;diff(x(:)) ~= 0;true]);
c = diff(y);
v = x(y(1:end-1));
method 1:
b = cell2mat(arrayfun(@(z)(1:z)',c,'uniformout',false));
method 2:
b = ones(size(x));
b(y(2:end-1)) = 1-c(1:end-1);
b = cumsum(b);
method 3:
g = (1:max(c))'*ones(1,numel(c));
b = g(bsxfun(@ge,c,1:max(c))');
Speed comparison:
% The testing data;
x = cell2mat(arrayfun(@(y,z)(y+zeros(1,z)), ...
randi(100,10000,1),randi(2000,10000,1),'uniformout',false));
% Method 1; 0.25 sec
% Method 2; 0.17 sec
% Method 3; 1.05 sec
Method 2 is better.
No comments:
Post a Comment