我们使用的GNSS数据或者水位数据是日监测数据,为了数据时间分辨率的一致性,我们通常需要将日数据取平均为月数据,下面我介绍两种基本的思路。注意:此处的时间变化已经变成了下面的格式。基本的思路是,再数据添加一列,把每一个年中月份相同的添加相同的标记(此处我是按照序数1、2、3...排列),方便后续的数据汇总取平均值。
yyyy mm dd
2020 01 01
. . .
. . .
2020 12 31
(1)日、月份匹配
针对于平年和闰年,我们在循环中添加IF条件,判断读取的月份是否满足对应的月份。关键是实现标记的添加,实现的代码如下:
function out = Day2Month_leap(time,yy,mm,dd)
% time: n x 3 : year, month, day
% yy : n x 1 : year
% mm : n x 1 : month
% dd : n x 1 : day
% out : n x 4 : year, month, day, label
o = 1;
month_daylist = [31,28,31,30,31,30,31,31,30,31,30,31];
month_daylist_leap = [31,29,31,30,31,30,31,31,30,31,30,31];
for i = 1:length(mm)
for j = 1:12
if(mm(i)==j)
time(i,4)=o;
if leapyear(yy(j)) == 1
if(dd(i)==month_daylist_leap(j))
o = o+1;
end
else
if(dd(i)==month_daylist(j))
o = o+1;
end
end
end
end
end
out = time;
我们可以看到,通过判断天数是否达到一个月的最后一天而判断标记数是否需要加1.有一个缺陷是:当每天监测的数据不完整时,这个方法会出现问题。适用于数据监测完整、规律。下面介绍另外一种稳健的方法
(2)月份差分法
现在问题最大的地方在于如何在适当的位置添加label,因此可以考虑,循环对月份处理,并前后做差,当两次的月份差异不为0时,意味着发生了突变,即需要对label增加1.具体代码如下
function [out,m_label] = Day2Month_diff(time,mm)
% time: n x 3 : year, month, day
% mm : n x 1 : month
% out : n x 4 : year, month, day, label
% m_label: month
o = 1;
m_label = [];
for i = 1:length(mm)-1
for j = 1:12
if(mm(i)==j)
time(i,4)=o;
if((mm(i+1)-mm(i))~=0)
o=o+1;
m = i;
m_label = [m_label,m];
end
end
end
if(i==length(mm)-1)
time(end,4)= time(end-1,4);
m_label = [m_label,i];
end
out = time;
end
需要注意对最后一个月的处理,我这里是单独进行了一次判断。这个方法可以用于监测数据不完整的数据。接着采用tabulate函数可以查看对应的相同label的数量。最后就可以对相同label的数据进行平均。
欢迎点赞收藏!