## How do I take the average of every n values in a vector?

Brooks

### Brooks (view profile)

さんによって質問されました 2013 年 6 月 27 日

### Stelios Fanourakis (view profile)

さんによって 編集されました 2019 年 5 月 19 日
Matthew Eicholtz

### Matthew Eicholtz (view profile)

さんの 回答が採用されました
I have some data on Pulse Rate and the sample was taken at 1000 Hz (One sample every millisecond), way too big for what I want to see. My vector is 399277x1 and I want to be able to average every 1000 values and get that number in a new vector of somewhere around 400x1. Is there any way to do this?
Thanks

#### 0 件のコメント

サインイン to comment.

## 5 件の回答

### Matthew Eicholtz (view profile)

2013 年 6 月 27 日
採用された回答

Try this...
n = 1000; % average every n values
a = reshape(cumsum(ones(n,10),2),[],1); % arbitrary data
b = arrayfun(@(i) mean(a(i:i+n-1)),1:n:length(a)-n+1)'; % the averaged vector

ALI DASMEH

2019 年 1 月 5 日
Thanks alot Man!
Image Analyst

### Image Analyst (view profile)

2019 年 1 月 5 日
Note one difference. My answer below using blockproc() gets the average of the final 277 elements, even though it's not a full block of 1000, while Matthew's does not (it skips those values).
So Matthews array and Jan's result are 399 long, while mine and Andrei's results are the full 400 long.
You have to decide what you want. Do you want the average of the final, partial block, or not?

2019 年 1 月 5 日
COOL! thank you

サインイン to comment.

2013 年 6 月 28 日

### Jan (view profile)

2019 年 5 月 17 日

x = rand(399277, 1); % Some example data
n = 1000; % Number of elements to create the mean over
s1 = size(x, 1); % Find the next smaller multiple of n
m = s1 - mod(s1, n);
y = reshape(x(1:m), n, []); % Reshape x to a [n, m/n] matrix
Avg = transpose(sum(y, 1) / n); % Calculate the mean over the 1st dim

#### 7 件のコメント

Stelios Fanourakis

### Stelios Fanourakis (view profile)

2019 年 5 月 16 日
Sorry. My misinterpratation. When I say "x axis", I meant the data on the x axis, which are numeric values that correspond to certain y values.
How you interpret blockwise (blocks of n elements?). I have the sense that we tell the same thing.
Imagine there is an array of n elements, distributed in the x coordinate. You split them into intervals and average each interval seperately and then alltogether? How are you actually doing this?
Jan

### Jan (view profile)

2019 年 5 月 17 日
@Stelios: It is not clear what "data on the x axis" should be. I guess you mean a trivial object called "vector", e.g.:
x = rand(1, 100)
This is a vector of 100 elements. Altough it is called "x", it does not have any relation to an axis. You can call it bananaProduction also. You cannot claim, that these vales are "distributed in the x coordinate", because this term is not even meaningful in a mathematical sense.
You see in the code I have posted, how it is treated in blocks of n elements, let's use e.g. 5. Then the 1D vector can be reshaped efficiently into a 2D matrix with 5 rows and 20 columns:
y = reshape(x, 5, 20);
To create the mean over the columns, Matlab offers the command mean() and let us specify the dimension to operate on:
avg_x = mean(y, 1);
In my code I've used sum(M, 1) / n, because it is sligthtly faster, but of course we get the same result.
The code in my answer considers in addition that the number of elements of x need not be a multiple of n. Then
s1 = size(x, 1);
M = s1 - mod(s1, n) % next smaller mutliple of n
Is the next smaller mutliple of n, such that the number of elements in x(1:M) is divisable by n.
Stelios, my code has 4 lines only and it uses only very basic Matlab commands. Therefore it is hard to answer "How are you actually doing this?"
Stelios Fanourakis

### Stelios Fanourakis (view profile)

2019 年 5 月 19 日
@Jan
x = rand(399277, 1); % Some example data
n = 1000; % Number of elements to create the mean over
s1 = size(x, 1); % Find the next smaller multiple of n
m = s1 - mod(s1, n);
y = reshape(x(1:m), n, []); % Reshape x to a [n, m/n] matrix
Avg = transpose(sum(y, 1) / n);
Although, it is consist of 6 simple code lines I wasn't familiar with the though behind it.
For instance, in this case, as your example data you used a vector of 399277 rows in a single column. You chose to find the mean per 1000 elements (n). I didn't quite understand why you are trying to find the next smaller multiple of n. I suppose you want integers to perfectly divide the x and not decimals. Am I correct?
You then reshape the matrix for faster computation, probably?
And what this transpose stands for? You calculate the mean over the first dimension of y, since the second one is the n. Right?

サインイン to comment.

2013 年 6 月 27 日

### Image Analyst (view profile)

2019 年 1 月 5 日

Here is how I'd do it (an alternate way), using blockproc to average in 100 element long blocks in "jumps":
% Create sample data
PulseRateF = rand(399277, 1);
% Define the block parameter. Average in a 100 row by 1 column wide window.
blockSize = [1000, 1];
% Block process the image to replace every element in the
% 100 element wide block by the mean of the pixels in the block.
% First, define the averaging function for use by blockproc().
meanFilterFunction = @(theBlockStructure) mean2(theBlockStructure.data(:));
% Now do the actual averaging (block average down to smaller size array).
blockAveragedDownSignal = blockproc(PulseRateF, blockSize, meanFilterFunction);
% Let's check the output size.
[rows, columns] = size(blockAveragedDownSignal)

Image Analyst

### Image Analyst (view profile)

2019 年 5 月 13 日
It scans a window, of 1000 elements long, along the array in "jumps" of 1000, taking the average of those 1000 elements in the array. Thus the result will be the means in an array 1/1000 of the length of the original array. It should do what you want. It's just an alternative way to doing it via reshape() like Jan suggested. This has the advantage that the array does not need to be a multiple of 1000 long to work (it will just average whatever remainder is left at the right end of hte array), and it can be configured to do a scan of a 2-D matrix if you have that situation.
Stelios Fanourakis

### Stelios Fanourakis (view profile)

2019 年 5 月 16 日
I am not sure whether I understood it well. I use this
% Create sample data
PulseRateF = Pd;
% Define the block parameter. Average in a 100 row by 1 column wide window.
blockSize = [300, 100];
% Block process the image to replace every element in the
% 100 element wide block by the mean of the pixels in the block.
% First, define the averaging function for use by blockproc().
meanFilterFunction = @(theBlockStructure) mean2(theBlockStructure.data(:));
% Now do the actual averaging (block average down to smaller size array).
blockAveragedDownSignal = blockproc(PulseRateF, blockSize, meanFilterFunction);
% Let's check the output size.
[rows, columns] = size(blockAveragedDownSignal)
And I get
rows = 5 columns = 1
What those numbers mean?
Jan

### Jan (view profile)

2019 年 5 月 16 日
Look at the code: These numbers are the size of the variable blockAveragedDownSignal.

サインイン to comment.

2013 年 6 月 28 日

### Andrei Bobrov (view profile)

2017 年 7 月 28 日

x = randi(1000,399277,1);
n = 1000;
m = numel(x);
out = nanmean(reshape( [x(:);nan(mod(-m,n),1)],n,[]));
or
out = accumarray(ceil((1:numel(x))/1000)',x(:),[],@mean);

#### 2 件のコメント

Shannon Ross-Sheehy

### Shannon Ross-Sheehy (view profile)

2019 年 3 月 2 日
This answer is simple and perfect. Thanks!
Stelios Fanourakis

### Stelios Fanourakis (view profile)

2019 年 5 月 13 日
@Andrei Bobrov
What this actually does? Does it average in a step of n intervals along the x axis? This is what I am looking for. Hope this does what I want.
I want to divide the x axis into intervals and average between them.

サインイン to comment.

2017 年 1 月 20 日

Alexey

### Alexey (view profile)

2018 年 11 月 1 日
Great solution! Thanks!

サインイン to comment.

Translated by