How to combine series of consecutive numbers in Matlab?
3 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
Stephen23
2018-6-8
编辑:Stephen23
2018-6-8
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
更多回答(2 个)
John D'Errico
2018-6-8
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)) = [];
Kaninika Pant
2018-6-8
编辑:Kaninika Pant
2018-6-8
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
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Loops and Conditional Statements 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!