more efficient way of using for loop?

1 次查看(过去 30 天)
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 个评论
Stephen23
Stephen23 2017-10-3
编辑:Stephen23 2017-10-3
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.

请先登录,再进行评论。

回答(1 个)

Guillaume
Guillaume 2017-10-3
编辑:Guillaume 2017-10-3
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 个评论
Roisin Loughnane
Roisin Loughnane 2017-10-3
I figured it out:
The cell monthlydata was being changed to a class double outside the inner loop, so I just changed the name
monthlydatac = cat(3, monthlydata{:});
monthlymean = mean(monthlydatac, 3);
Guillaume
Guillaume 2017-10-3
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.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Creating and Concatenating Matrices 的更多信息

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by