0

I have a time series data or considering a real valued data of length N. I want to create sub-blocks of length k, which is the window length. The value of k can be arbitrarily chosen. This creates problem since the window size is the same across the data. I want to store each subblock in an array. But I am stuck in creating sub-blocks of the data and to include a check so that the (mod(N, nseg)) nseg must be divisible by the data length.

N = 512; %length of the time series
data = rand(N,1);
window_length = 30;  %k
Nseg = floor(N/window_length) %Number of segments or blocks

Modified_Data = [mean(reshape(data,window_length,Nseg))]; %Throws error 
horchler
  • 18,384
  • 4
  • 37
  • 73
Srishti M
  • 533
  • 4
  • 21

3 Answers3

2

If you have the Image Processing toolbox you could use im2col to slide a specific block size over the entire time series. Each column of the output represents the data from one of those blocks.

values = im2col(data, [window_length 1], 'distinct');

Since it looks like you just want the mean over each block, you could also use blockproc to do this.

means = blockproc(data, [window_length, 1], @(x)mean(x.data));

If you do not have the Image Processing Toolbox, you can instead use accumarray to perform this task.

means = accumarray(floor((0:(N-1)).'/window_length) + 1, data, [], @mean);

If you want to discard any data that extends beyond a number which is divisible by window_length, you can do this with something like the following:

data = data(1:(numel(data) - mod(numel(data), window_length)));

If you want overlapping data, you'll either want to use straight-up convolution (the preferred method)

means = conv(data(:), ones(5, 1)/5, 'same');

Or you can create overlapping blocks with im2col by omitting the last input.

values = im2col(data, [window_length 1]);
means = mean(values 1);
Suever
  • 64,497
  • 14
  • 82
  • 101
  • Thank you for your reply. I do have the im2col() function. I would like to know that apart from creating non-overlapping blocksizes, how can I apply the method to create overlapping blocks? I do not want the mean value over sliding window for overalpping. Let the data contain 5 elements say data = [1,2,3,4,5]. Then the blocks would be blck1 = (0,1); blk2 = (1,2); blk3 = (2,3); blk4 = (3,4); blk5 = (4,5)? So, could you please put up an answer for non-overlapping (the one that you already have) and for the overlapping case that I have mentioned in this comment? Thank you very much! – Srishti M Jun 11 '16 at 01:48
  • You would just want to omit the 3rd input to `im2col`: `im2col([1 2 3 4 5], [1 2])` – Suever Jun 11 '16 at 01:50
  • @SrishtiM Updated. – Suever Jun 11 '16 at 01:51
2

If you have R2016a+, consider using the built-in movmean function:

N = 512; %length of the time series
data = rand(N,1);
window_length = 30;  %k
Modified_Data = movmean(data, window_length);

See the documentation for further details and other options.

horchler
  • 18,384
  • 4
  • 37
  • 73
0

If I understand your question correctly, it's pretty straightforward:

filter(ones(N,1)/N,1,signal)

If you think about it filtering with [1/N 1/N 1/N...1/N] is exactly calculating the localized mean...

Suever
  • 64,497
  • 14
  • 82
  • 101
Uri Merhav
  • 300
  • 2
  • 13
  • @Suever you can just choose every `N` elements of the result. Otherwise, `conv` might be more straightforward here than `filter`, maybe they're the same for that kernel but `conv` definitely gives you the means – Dan Jun 10 '16 at 23:51