# Creating blocks of average values from a series but avoiding dynamic variable names

2 views (last 30 days)
Anthony Phipps on 13 Feb 2021
Commented: Paul Hoffrichter on 15 Feb 2021
Hi
I am trying to avoid using dyanmic variable names for all the good reasons listed:
My challenge
I have two long series of numbers stored in a single row matrix that I need to compare but in a particular way.
They are sutbley different. I'm ok to compare them but the first step I need to do is giving me a challenge. I need to break each series into groups (the length of which is a variable), take an average of each group, and store the recovered averages in a matrix.
Then I need to compare the results and the differnce is the answer I am looking for.
The bit that has me vexed is how to do this without using a for loop and dynamic named variables. If I try using the index its not having the desoired outcome despite much experimentation. Here a little test version of what I'm trying to do:
clear;
mynumberc = 100 * rand(1, 505);
lenny = length(mynumberc);
group_size = 100;
numberofgroups = floor(lenny/group_size);
nextstart = 1;
nextstop = group_size;
groupdata = [0];
group_ave = [0];
for i = 1:1:numberofgroups
for c = nextstart:1:nextstop
groupdata(c) = mynumberc(c)
nextstart = nextstart + 1
nextstop = nextstop + 1
end
group_ave(i, end+1) = mean (groupdata)
i = i + 1;
end
group_ave = group_ave (2:end)
return
In this example I'd want the first 500 values of mynumberc to be split into 5 100 value chunks, each chunk averaged and then put in an array of averages called group_ave. The actual use of this will be at much bigger scale which is why I want to avoid dynamically named variables.
Stephen23 on 15 Feb 2021
Edited: Stephen23 on 15 Feb 2021
Your code has a number of "features" which make it complex and inefficient. For example:
• on the first of the outer loop iteration the variable groupdata expands on each inner loop iteration.
• group_ave expands on each outer loop iteration.
• the inner loop can be replaced with some indexing (hint: group_size).
• i = i + 1 is completely superfluous and misleading: the for operator increments i already.
• superfluous square brackets around scalar values should be removed.
• "remove leading zero element" can be easily avoided (hint: empty or preallocation).
• return is not required.
It is not clear why you expect the output to be a matrix:
group_ave(i, end+1) = ..
If you take the mean of N "groups", then that will give N values which can be trivially arranged in a vector. That matches with the row indexing... but then why do you also increment the column index?
Anthony Phipps on 15 Feb 2021
Thanks for this. It turns out I dont need the for loops and as you suggest it can be done by arranging the vector.
Thanks for the guidance and also the pointers on the correct syntax.
Many thanks

Paul Hoffrichter on 15 Feb 2021
Since you have 5 groups of 100 numbers, I thought you wanted the mean of each group. That gives 5 means. So I did not understand why you say "store the recovered averages in a matrix" rather than storing the 5 means in a vector. Below shows how to store the 5 means in a vector.
rng(1234);
mynumberc = 100 * rand(1, 505);
lenny = length(mynumberc);
group_size = 100;
numberofgroups = floor(lenny/group_size);
myGroupNumberC = mynumberc(1:group_size*numberofgroups);
myNumberChunks = reshape( myGroupNumberC, group_size, numberofgroups);
muGroupMeans = mean(myNumberChunks) % meanof each column
Anthony Phipps on 15 Feb 2021
Wow - thanks
I had fallen into the trap of thinking I had to use a nested loop so this looks like the work of a MATLAB jedi!
This is a much more elegant solution - no need for looping at all. This is just as well as it will be used with much larger numbers and numbers of groups so looping would have been slow.
Many thanks!
Paul Hoffrichter on 15 Feb 2021
You're very welcome!