时间序列数据求平均(时间抽稀)

背景

在时间序列数据处理中,原始时间序列采样间隔非常密集,有的为分钟级,有的甚至是秒级,在分析时,依据分析目的不同,需要进行不同尺度的转化,若要查看其日变化情况或季节变化,直接使用海量的秒级原始数据,其整体变化特征通常会被大量的细节数据所掩盖。所以求取日平均、月平均等是常见的操作。

这里利用matlab数据内置的find、mean等函数,可以方便的求得。算法不一定是最优的,但是,可以实现目的,记录于此,便于日后查找,也为不想自己编写的朋友提供参考。

问题描述

以某地温度时间序列为例,该数据的时间分辨率为秒级,数据量非常大,第一列为时间数据,第二列为温度数据。
在这里插入图片描述 数据截图

如何求取时平均呢?

解决思路

首先,将第一列化为日期向量的形式。

mydata=datevec(dd(:,1)); %将日期字符串化为日期向量

然后通过循环,求取统一比较时间级别的量,这里核心用find函数,具体代码如下

temp=data(:,1:n);
temp=temp-dd;
temp=abs(temp);%必须加绝对值,防止正负抵消的情况,浑水摸鱼
s0=sum(temp,2);
bz1=find(s0==0);

然后,将在范围之内的数据进行平均,得到该时间级别上的平均值,将剩余的数据赋值给原始数据,继续进入下一轮的循环

最后,当剩余矩阵为空时,则循环结束。

需要注意的两个地方:

(1)判断时间级别相同,采用了向量减法,然后对结果进行求和,可能会出现正负抵消的情况,此时,从结果上看,也是为0,而这和要比较的时间级别是不同的,序号对差求取绝对值,以剔除这种情况。

(2)求和函数,要区分是列方向求和还是行方向求和,这个细节可以参阅matlab帮助,实在不行,用一个简答的小矩阵进行试验,当结果正确的时候,则证明算法是正确的。

完整的代码如下:

mydata=datevec(dd(:,1)); %将日期字符串化为日期向量
t=dd(:,2);               %提取温度数据
t=cell2mat(t);           %将细胞数据转化为矩阵
mydata=[mydata t];       %合并数据
tempdata=mydata;         %暂存原始数据,防止出错,原数据被污染。
rsltData=[];
idx=1;
numD=2;%需要平均的维数,1-年 2-月 3-日 4-时 5-分 6-秒
while 1
    [bz1,bz2]=findsamehour(tempdata,tempdata(1,1:numD));
    rsltData(idx,1:numD)=tempdata(1,1:numD);
    rsltData(idx,numD+1:6)=0;            %为了严谨,平均时间尺度以下的值赋为0,避免具体时间造成误导
    dataInRegion=tempdata(bz1,:);     %需要平均的数据,7仅是本数据的特列,具体数据所在列数以具体情况而定
    dataOutRegion=tempdata(bz2,:);
    rsltData(idx,7)=mean(dataInRegion(:,7));
    if(length(bz2)<=0)
        break;
    end
    idx=idx+1;%序号递增,进入下一轮循环
    tempdata=dataOutRegion;% 更新mydata的值
    idx
end

搜索统一时间段的函数

`

function [bz1,bz2]=findsamehour(data,dd)
% y=2018;
% m=1;
% d=1;
% h=0;
[m,n]=size(data);
if(n<6)
    error('输入的数据列小于6')
    return;
end
[m,n]=size(dd);
if(n>6)
    error('输入的时间向量列维数大于6')
    return;
end
temp=data(:,1:n);
temp=temp-dd;
temp=abs(temp);%必须加绝对值,防止正负抵消的情况,浑水摸鱼
s0=sum(temp,2);
bz1=find(s0==0);
bz2=find(s0~=0);
end

绘图函数

%% 绘图
afigure;
aplot(dt,mydata(:,7),'.g');
xlabel('time');
ylabel('temperature(℃)');
hold on
aplot(datetime(rsltData(:,1:6)),rsltData(:,7),'-r');
xtickformat('MM-dd')
aplot(datetime(rsltData2(:,1:6)),rsltData2(:,7),'o:b');
legend({'raw data','hour mean data','month mean data'})
axis tight

结果

最终结果可以用图直观表示

在这里插入图片描述

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值