在MATLAB中创建重叠和不重叠的滑动窗口 [英] Create overlapping and non-overlapping sliding windows in MATLAB
问题描述
N
元素的数组Data
中创建重叠和不重叠的数据块.如何为任何N
和任何blksze
正确形成Data
的子数组?以下代码用于非重叠块引发错误,因为创建子块时元素数超出了.例如,让Data = [1,2,3,4,5,6]
,然后
-
对于重叠的情况,我应该得到:块大小
blksze = 2
,我会得到block1 = [1,2], block2 = [2,3], block3 = [3,4], block4 = [4,5], block5 = [5,6]
-
对于不重叠的:块大小
blksze = 2
,我会得到block1 = [1,2], block2 = [3,4], block3 = [5,6]
代码段
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
要提取出重叠的块,建议使用 reshape
.
重叠
ind = bsxfun(@plus, (1 : blksze), (0 : numel(Data) - blksze).');
此方法的优点是它使用广播来为每个块生成正确的索引.因此,这将是一个2D矩阵,其中每一行都是获取正确块数据所需的索引,并且列数由块大小决定.
不重叠
ind = reshape(1 : numel(Data), [], numel(Data) / blksze).';
这只是对向量进行整形,以便每一行都是唯一的索引集,该索引集将增加1,并且列数由块大小决定.
最后,只需索引到Data
即可获得所需的内容:
blocks = Data(ind);
这是一个使用6个元素的运行示例:
>> rng(123); Data = rand(1, 6)
Data =
0.6965 0.2861 0.2269 0.5513 0.7195 0.4231
块大小为2或blksze = 2
的是重叠和不重叠的结果:
>> 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
注意
此代码不进行错误检查,因为我们假设有足够的块来捕获您的所有数据.如果Data
中的元素数与块大小不兼容以捕获所有相同大小的块中的所有数据,则在建立索引时会发生错误.
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
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.
这篇关于在MATLAB中创建重叠和不重叠的滑动窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!