2016-10-11 30 views
4

我有一个大的整个地球的空气温度的三维矩阵,数据格式化为每小时分辨率的lon x lat x时间。我想找到一个可靠的方法来计算每个纬度/经度位置的日最低温度。举例:计算3d矩阵数据的每日最小值

lon = -180:10:180; 
lat = -90:10:90; 
time = datenum('2009-01-01 00:00','yyyy-mm-dd HH:MM'):1/24:datenum('2009-01-05 23:00','yyyy-mm-dd HH:MM'); 
data = randn(length(lon),length(lat),length(time)); 

这是我的数据。它包括按小时分辨率提供的不同位置的气温。下面的代码是我计算每一天的最小值的尝试。

% find number of unique days 
datev = datevec(time); 
[ia,ib,ic] = unique(datev(:,1:3),'rows'); 
uic = unique(ic); 

% first re-structure data to 2d matrix 
rdata = nan(length(time),length(lon)*length(lat)); 
for i = 1:length(ic); 
    dd = data(:,:,i); 
    rdata(i,:) = dd(:);   
end 

% then calculate the minimum value for each day 
min_data = nan(length(uic),length(lon)*length(lat)); 
for i = 1:length(uic); 
    idx = find(ic == uic(i));  
    min_data(i,:) = min(rdata(idx,:),[],1); 
end 
min_data = reshape(min_data,length(lon),length(lat),length(uic)); 

我想这个答案是正确的,至少是似乎是当我在看答案。我的问题是(1)我的方法是否正确,(2)是否有更好的方法来做到这一点,而不是重新构造数据,并在不同的不平常的日子里循环。我考虑使用准系数,但不知道如何使用3d矩阵进行工作。

任何爱慕的赞赏。

回答

3

您可以使用从unique输出的第三个输出作为accumarray的输入来对数据进行分组。作为第二个输入,您可以提供1与您的数据大小(numel(ic))之间的所有数字。然后,对于第四个输入,您可以创建一个匿名函数,该函数将接收对应于每天的索引(对于第三维),并且可以使用它们来获取当天所有经度/纬度的临时值,并且可以计算最小值通过沿着第三维计算min来计算每个纬度/经度。

datev = datevec(time); 
[~,~,ic] = unique(datev(:,1:3),'rows'); 

min_temps = accumarray(ic, (1:numel(ic))', [], @(x){min(data(:,:,x), [], 3)}); 
min_temps = cat(3, min_temps{:}) 

这种方法的好处是它不一定每天需要24个样本。如果可以保证24个样本,那么您可以重新整理数据,然后计算min而不使用accumarray

reshaped = reshape(data, size(data, 1), size(data, 2), 24, []); 
min_temps = squeeze(min(reshaped, [], 3));