Split cell array taking into account difference between elements
1 view (last 30 days)
Show older comments
Dimitris Kokkinos
on 3 Dec 2014
Commented: Dimitris Kokkinos
on 3 Dec 2014
Hello! I have a cell array which contains indices from another cell array.Lets say for example
TES={[1;2;3;4;5];[12;13;14];[1;2;3;4;8;9;10;22;23;24];[4;5;6;8;9];[5;6;7]};
Where the indices have no jump at their sequence (cases 1,2 & 5) I want to keep the cell as it is. Where the jump is smaller than 2 I also want to keep the cell as it is(cell 4) But where there is a jump(or more) greater than 2 I need to split each cell into other cells.Their Number should be (jumbs+1).
The desirable result is
TES_new={[1;2;3;4;5];[12;13;14];[1;2;3;4];[8;9;10];[22;23;24];[4;5;6;8;9];[5;6;7]};
0 Comments
Accepted Answer
Guillaume
on 3 Dec 2014
Edited: Guillaume
on 3 Dec 2014
A fairly simple way of doing it:
TES={[1;2;3;4;5];[12;13;14];[1;2;3;4;8;9;10;22;23;24];[4;5;6;8;9];[5;6;7]};
runlengths = cellfun(@(m) diff([0; find(diff(m) > 2); numel(m)]), TES, 'UniformOutput', false);
splits = cellfun(@(m, runs) mat2cell(m, runs), TES, runlengths, 'UniformOutput', false);
TES_new = vertcat(splits{:})
You can combine both cellfun for a little bit more speed at the expense of readability:
splits = cellfun(@(m) mat2cell(m, diff([0; find(diff(m) > 2); numel(m)])), TES, 'UniformOutput', false);
TES_new = vertcat(splits{:})
4 Comments
Guillaume
on 3 Dec 2014
If I understood correctly, this is what you want:
TES={[1;2;3;4;5] 10;[12;13;14] 2;[1;2;3;4;8;9;10;22;23;24] 6;[4;5;6;8;9] 4;[5;6;7] 8} %for example
runlengths = cellfun(@(m) diff([0; find(diff(m) > 2); numel(m)]), TES(:, 1), 'UniformOutput', false);
splits = cellfun(@(m, runs) mat2cell(m, runs), TES(:, 1), runlengths, 'UniformOutput', false);
indices = cellfun(@(i, runs) repmat(i, numel(runs), 1), TES(:, 2), runlengths, 'UniformOutput', false);
TES_new = [vertcat(splits{:}) num2cell(vertcat(indices{:}))]
More Answers (2)
Thorsten
on 3 Dec 2014
This is somewhat similar to Star Strider's solution but with an extra index ind_new to get rid of the subarrays and with a copy of those arrays that need not to be split to the new cell:
TES={[1;2;3;4;5];[12;13;14];[1;2;3;4;8;9;10;22;23;24];[4;5;6;8;9];[5;6;7]};
i_new = 1;
for i=1:numel(TES)
split = find(diff(TES{i}) > 2);
if isempty(split)
TES_new{i_new} = TES{i};
i_new = i_new + 1;
else
ind = [0 split' numel(TES{i})];
for ii = 1:numel(ind2)-1
TES_new{i_new} = TES{i}(ind(ii)+1:ind(ii+1));
i_new = i_new + 1;
end
end
end
for i=1:numel(TES_new)
disp(TES_new{i})
end
0 Comments
Andrei Bobrov
on 3 Dec 2014
n = cellfun(@numel,TES);
ii = accumarray(cumsum([1;n]),1);
ii = ii(1:end-1);
T = cat(1,TES{:})
jj = [1; abs(diff(T))>2];
out = accumarray(cumsum([jj | ii]),T,[],@(x){x})
0 Comments
See Also
Categories
Find more on Logical 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!