问题
I am trying to create overlapping and non-overlapping blocks of data from an array Data
containingN
elements. How can I correctly form sub-arrays of Data
for any N
and any blksze
? The following code is for non-overlapping blocks throws error because of the number of elements exceed when creating sub-blocks. For example, let Data = [1,2,3,4,5,6]
, then
for overlapping case I should get : block size
blksze = 2
, I would getblock1 = [1,2], block2 = [2,3], block3 = [3,4], block4 = [4,5], block5 = [5,6]
for non-overlapping : block size
blksze = 2
, I would getblock1 = [1,2], block2 = [3,4], block3 = [5,6]
Code snippet
N= 100;
n = 4;
Data = randi([1 n],1,N);
blksze = 10;
Nblocks = N / blksze;
counter = 1;
for i = 1 : Nblocks
block{i} = Data(counter : counter + blksze - 1);
counter = blksze + 1;
end
回答1:
To extract out overlapping blocks, I recommend using bsxfun to create the indices and subset the matrix whereas non-overlapping blocks you can simply use reshape.
Overlapping
ind = bsxfun(@plus, (1 : blksze), (0 : numel(Data) - blksze).');
The advantage of this method is that it uses broadcasting to generate the right indices per block. This would thus be a 2D matrix where each row are the indices required to grab the data for the right block and the number of columns is dictated by the block size.
Non-overlapping
ind = reshape(1 : numel(Data), [], numel(Data) / blksze).';
This simply reshapes the vector so that each row would be a unique set of indices that increases by 1 and the number of columns is dictated by the block size.
Finally, just index into Data
to get what you need:
blocks = Data(ind);
Here's a running example using 6 elements:
>> rng(123); Data = rand(1, 6)
Data =
0.6965 0.2861 0.2269 0.5513 0.7195 0.4231
With a block size of 2, or blksze = 2
, here's what we get for both overlapping and non-overlapping:
>> blksze = 2;
>> indno = reshape(1 : numel(Data), [], numel(Data) / blksze).';
>> indo = bsxfun(@plus, (1 : blksze), (0 : numel(Data) - blksze).');
>> blockno = Data(indno)
blockno =
0.6965 0.2861
0.2269 0.5513
0.7195 0.4231
>> blocko = Data(indo)
blocko =
0.6965 0.2861
0.2861 0.2269
0.2269 0.5513
0.5513 0.7195
0.7195 0.4231
Caveat
This code does no error checking in that we assume that there are enough blocks to capture all of your data. If you have the number of elements in Data
to be incompatible with the block size to capture all of the data in blocks of all the same size, an error will occur upon indexing.
来源:https://stackoverflow.com/questions/42284204/create-overlapping-and-non-overlapping-sliding-windows-in-matlab