我有一个大的三维空气温度矩阵,整个地球,数据格式为lon x lat x时间分辨率。我想找到一种计算每个纬度/经度位置的每日最低温度的有效方法。一个例子:
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)是否有更好的方法,而不是必须重组数据并循环不同的uniuque天。我考虑过使用accumarray,但是可以解决如何使用3d矩阵进行处理的问题。
任何adive表示赞赏。
答案 0 :(得分: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));