more efficient way of using for loop?

조회 수: 1 (최근 30일)
Roisin Loughnane
Roisin Loughnane 2017년 10월 3일
댓글: Guillaume 2017년 10월 3일
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에서 Logical에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by