How to select several intervals from a vector?

I have a vector (Y). I want to select a region from this vector. If this is a single region it is easy
X=Y(i_from:i_to);
What if I have several regions (the number of regions is not fixed)?
So I want to make the vector
[Y(i_from_1:i_to_1) ,Y(i_from_2:i_to_2), ........ ,Y(i_from_n:i_to_n)]
where n is not fixed.
Is there a fast and simple way? i_from and i_to values are in a n*2 matrix.
I can of course do a for cycle, but looking for a simpler method.

 Akzeptierte Antwort

Kristoffer
Kristoffer am 10 Okt. 2023

2 Stimmen

You can make a vector containing the values specified by the intervals in Y using:
cell2mat(arrayfun(@(A,B) A:B, Y(:,1)', Y(:,2)', 'uniform', 0))

3 Kommentare

Csaba
Csaba am 26 Apr. 2024
Bearbeitet: Csaba am 26 Apr. 2024
This is not what I want.
Let say I have
Y=1:2:30;
intervals=[1,3;...
11,15];
Then the desired output would be:
[1,3,5,21,23,25,27,29]
If you change Y to intervals in @Kristoffer's expression, we get your desired output
Y=1:2:30;
intervals=[1,3;...
11,15];
Y(cell2mat(arrayfun(@(A,B) A:B, intervals(:,1)', intervals(:,2)', 'uniform', 0)))
ans = 1x8
1 3 5 21 23 25 27 29
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Csaba
Csaba am 26 Apr. 2024
OK, this works. Thank you!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

DGM
DGM am 26 Nov. 2021
Bearbeitet: DGM am 26 Nov. 2021
Idk. Here's three ways. They all use loops. Is there something more elegant? Prrrrobably. Is it faster? Probably depends. I'm sure there's more to be said about the topic. I'll leave that for others.
A = rand(1,1000);
bex = randi([1 1000],50,2);
timeit(@() loopappending(A,bex))
ans = 1.9935e-04
timeit(@() loopindexing(A,bex))
ans = 1.5171e-04
timeit(@() loopcell(A,bex))
ans = 1.1135e-04
% simply append subvectors
function B = loopappending(A,bex)
B = [];
for b = 1:size(bex,1)
B = [B A(bex(b,1):sign(diff(bex(b,:))):bex(b,2))];
end
end
% preallocate and use direct indexing
function B = loopindexing(A,bex)
B = zeros(1,sum(abs(diff(bex,1,2))+1)); % preallocate
endpoints = [0; cumsum(abs(diff(bex,1,2))+1)];
for b = 1:size(bex,1)
B(endpoints(b)+1:endpoints(b+1)) = A(bex(b,1):sign(diff(bex(b,:))):bex(b,2));
end
end
% throw output into cell array and then rearrange
function B = loopcell(A,bex)
B = cell(1,size(bex,1));
for b = 1:size(bex,1)
B{b} = A(bex(b,1):sign(diff(bex(b,:))):bex(b,2));
end
B = horzcat(B{:});
end

1 Kommentar

Csaba
Csaba am 26 Nov. 2021
Yes, cycles are an obvious solution. I am using that recently.
I am looking for a more elegant and faster method.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Loops and Conditional Statements finden Sie in Hilfe-Center und File Exchange

Produkte

Version

R2019b

Gefragt:

am 26 Nov. 2021

Kommentiert:

am 26 Apr. 2024

Community Treasure Hunt

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

Start Hunting!

Translated by