Eliminate nested FOR loop
    8 vues (au cours des 30 derniers jours)
  
       Afficher commentaires plus anciens
    
I have time series data in a double array.
The first column is datenum and all other columns are corresponding data
data = [NaN         101         102         103         104;
       731034         4           3         NaN           3;
       731035         5         NaN           2           1;
       731036         6           2           5           2;
       731037         3           1           4           7;
       731065         2           3         NaN           3;
       731066         5         NaN           5           1;
       731067         7           7           1           2;
       731068         3           4           4           7]
I need to work with monthly data.
For this, I run 3 loops, 1. one for columns 2. one for year 3. one for month
[Y, M] = datevec(data(2:end,1)); % first column contains dates
for i=2:1001 %loop through columns
    rcntr = 1;
    ccntr = ccntr +1;
    column_i = data(2:end,i); % fetch one entire column
    for yr=1995:2010
        for mo=1:12
            rcntr = rcntr + 1;
            monthly_data = column_i(M==mo & Y==yr);
            % do some calculations.
            mn = nanmean( monthly_data );
            storeresults(rcntr,ccntr) = mn;
        end
    end
end
Is there a way to simplify the above ? I basically need to get monthly data in each column. I am being told to use accumarray which I am reading up on. In the meantime any advice would be helpful.
0 commentaires
Réponses (2)
  José-Luis
      
 le 10 Jan 2013
        
      Modifié(e) : José-Luis
      
 le 10 Jan 2013
  
      The following snippet will give the average for each month, using the nanmean function. The first column of your_result is the first day of the averaged month. No loops are used but this comes at the cost of more memory. It would be simpler and probably faster to loop through every column of data.
your_data = [randi(42,1,11);[(721000:721000+999)' rand(1000,10)]];
%Getting rid of header
data=your_data(2:end,2:end);%(2:end,2:end);
[m n]=size(data);
fecha=your_data(2:end,1);
header = your_data(1,:);  
%Adding up monthly data
%Creating unique index for accumarray function, avoiding looping through
%columns
col=(1:n);
col_mat=repmat(col,m,1);
col_vec=col_mat(:);
fecha_vec=datevec(fecha);
%Reducing year idx 
orig_year=fecha_vec(:,1)-min(fecha_vec(:,1))+1;
year_idx = unique(year(fecha));
year_idx = datenum(year_idx,1,1); %idx given as first day of month
idx=[orig_year fecha_vec(:,2)];
month_idx=accumarray(idx,fecha,[],@min); 
idx=repmat(idx,n,1);
idx=[idx col_vec];
data=data(:);
%Aggregating data
meses=accumarray(idx,data,[],@nanmean,NaN);
%Rearranging in a three dimensional matrix
meses=reshape(permute(meses,[2 1 3]),length(year_idx)*12,n);
%Recreating and adding headers (column and vector)
month_idx=month_idx';
your_result=[header; [month_idx(:) meses]];
your_result(your_result(:,1) == 0,:) = [];
0 commentaires
  Jan
      
      
 le 10 Jan 2013
        
      Modifié(e) : Jan
      
      
 le 10 Jan 2013
  
      data2  = data(2:end, 2:1001);
[Y, M] = datevec(data(2:end,1)); % first column contains dates
Tick   = Y * 100 + M;            % A unique year+month identifier
uTick  = unique(Tick);           % List of ticks, sorted!
result = nan(numel(uTick), size(data, 2) - 1);
for iTick = 1:numel(uTick)
   result(iTick, :) = nanmean(data2(Tick == uTick(iTick), :), 1);
end
Instead of the loop accumarray could apply nanmean to the blocks also, but as long as I still struggle with the help text of this function, I prefer a for loop.
0 commentaires
Voir également
Catégories
				En savoir plus sur Dates and Time dans Help Center et File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


