more efficient way of using for loop?
1 view (last 30 days)
Show older comments
Hello everyone. I am new to Matlab and would really appreciate your help. I have a time series of multiple years of environmental data, which I would like to group together (here as a 3D array), get the mean and then save the mean output file for each month. My files are named by (datatype)_(year)_(month).asc
I attempted this by looping over the years and loading corresponding monthly files:
years = {'2003' '2004' '2005' '2006' '2007' '2008' '2009' '2010' '2011' '2012' '2013' '2014'}
%%January
for y = 1:length(years)
filename = strcat('sst_',num2str(years{y}),'_1.asc');
% read file in as array
load(filename)
end
and then concatenate the arrays, get the mean and save the output mean sea surface temperature file:
sst_climatology_1 = cat(12, sst_2003_1, sst_2004_1, sst_2005_1, sst_2006_1, sst_2007_1, sst_2008_1, sst_2009_1, sst_2010_1, sst_2011_1, sst_2012_1, sst_2013_1, sst_2014_1);
msst_1 = mean(sst_climatology_1,12);
dlmwrite('msst_1.csv',msst_1)
This is fine but obviously doing this 12 times for each month is ugly and unnecessary when I am sure there is a simple for loop or otherwise solution. Can somebody please point any solutions out to me please?
1 Comment
Stephen23
on 3 Oct 2017
Edited: Stephen23
on 3 Oct 2017
load-ing directly into the workspace is great fun from the command line, but should be avoided when writing real code, if you want it to be efficient and reliable:
You would avoid all of that awkward playing around lots of variables if you simply loaded into one variable.
Answers (1)
Guillaume
on 3 Oct 2017
Edited: Guillaume
on 3 Oct 2017
A few things:
- Creating your years cell array could be achieved more simply with:
years = compose('%d', 2003:2014);
- but since you're constructing your filename using num2str (which at present does nothing since years{y} is already a string), then you could just store it as an array of numbers:
years = 2003:2014;
- the first output of cat is not the number of matrices you concatenate, but in which dimension you concatenate, regardless of their number. If your sst_... matrices are 2D, then cat(3, ...) makes a lot more sense than cat(12, ...)
The main difficulty comes from the fact that you're using load without assigning its output, popping variables with varying name into existence. Giving an output to load would make your life easier. Here is how I would do it:
years = 2003:2014;
monthlydata = cell(1, numel(years)); %to hold the monthly data of each year. Preallocated.
for month = 1:12
for y = 1:numel(years)
monthlydata{y} = load(sprintf('sst_%d_%d.asc', years(y), month)); %load year_month into cell of cell array
end
monthlydata = cat(3, monthlydata{:}); %concatenate all cells along 3rd dimension
monthlymean = mean(monthlydata, 3); %get mean
dlmwrite(sprintf('msst_%d.csv', month), monthtlymean); %save
end
3 Comments
Guillaume
on 3 Oct 2017
That error can only come from the line
monthlydata{y} = ...
and only if monthlydata already exists and is not a cell array, which can't be the case if you've preallocated it with the line:
monthlydata = cell(1, numel(years));
Therefore the only way you get this error is if you haven't included that line.
See Also
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!