Azzera filtri
Azzera filtri

How to combine series of consecutive numbers in Matlab?

2 visualizzazioni (ultimi 30 giorni)
I have following data:
s{1} = 1:10;
s{2} = 19:27;
s{3} = 29:41;
s{4} = 59:67;
s{5} = 71:89;
s{6} = 91:110;
s{7} = 119:210;
s{8} = 214:290;
and I want to combine sets with difference less than 4
diff = s{2}(1)-s{1}(end)
if diff <4
combine s{1}and s{2}
My out should be:
s{1} = 1:10;
s{2} = 19:41;
s{3} = 59:67;
s{4} = 71:110;
s{5} = 119:210;
s{6} = 214:290;
  2 Commenti
Stephen23
Stephen23 il 8 Giu 2018
Modificato: Stephen23 il 8 Giu 2018
27 and 29 are not consecutive, so where does the 28 come from in the output? Or 90? Do you want any missing values to be added to the data in order to have all consecutive integers within that range?
Nikita Agrawal
Nikita Agrawal il 8 Giu 2018
Hi, thanks for responding. I would like all the acceptable gaps to be filled with consecutive numbers

Accedi per commentare.

Risposta accettata

Stephen23
Stephen23 il 8 Giu 2018
Modificato: Stephen23 il 8 Giu 2018
Bs = cellfun(@(v)v(1),s);
Es = cellfun(@(v)v(end),s);
D = Bs(2:end)-Es(1:end-1);
X = cumsum([1,D>=4]);
Bz = accumarray(X(:),Bs(:),[],@min);
Ez = accumarray(X(:),Es(:),[],@max);
Z = arrayfun(@(b,e)b:e,Bz,Ez,'uni',0);
Giving:
>> Z{:}
ans =
1 2 3 4 5 6 7 8 9 10
ans =
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
ans =
59 60 61 62 63 64 65 66 67
ans =
71 72 73 74 ... 106 107 108 109 110
ans =
119 120 121 122 ... 205 206 207 208 209 210
ans =
214 215 216 217 ... 286 287 288 289 290

Più risposte (2)

John D'Errico
John D'Errico il 8 Giu 2018
Loops are not terrible things, to be feared in MATLAB. Yes, it is true that often you can gain in speed by replacing nested loops, especially deeply nested loops. But a simple loop?
Never bother to optimize code that is not a time or memory sink. You just waste programmer time, which is far more valuable than a tiny amount of computer time. So unless your code is seen to be a bottleneck, then you are just wasting your time (and ours.) As well, often highly vectorized code is hard to read and understand.
So just write as a simple loop. BUT DON'T USE A VARIABLE NAMED DIFF. Never use variables with the same name as a function name. Especially one you will use often.
for n = 2:numel(s)
if s{n}(1)-s{n-1}(end) < 4
s{n} = s{n-1}(1):s{n}(end);
s{n-1} = [];
end
end
When that is done, some of the cells will now be empty. Just delete all empty cells, if that is a problem. That you can do simply enough in a vectorized way.
s(cellfun(@isempty,s)) = [];
  1 Commento
Nikita Agrawal
Nikita Agrawal il 8 Giu 2018
I agree to your view and thanks for bringing this into context. I am currently working on a more complicated loop and I see really less difference wrt to loop vs vectorization. Also, good that you pointed out diff not to be used. Thanks!

Accedi per commentare.


Kaninika Pant
Kaninika Pant il 8 Giu 2018
Modificato: Kaninika Pant il 8 Giu 2018
You can do the following in place of combine s{1} and s{2}:
1. Append the data of s{2} in s{1}: s{2}=[s{2}, s{1}];
2. Delete s{2}: s(2)=[];
Now you will have to do all this in a loop. The following would work:
del=1; %to store indices of the cells which will have to be removed
for i=2:8
diff=s{i}(1)-s{i-1}(end);
if diff<4
s{i-1}=[s{i-1}, s{i}]; %appending data
del=[del, i];
end
end
for i=2:length(del) %starting from 2 since del(1)=1 was only for initialization
disp(del(i)-i+2)
s(del(i)-i+2)=[]; %each time you delete the index of the next cell decreases by 1
end

Categorie

Scopri di più su Loops and Conditional Statements in Help Center e File Exchange

Tag

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by