假设我们在MATLAB R2015b中有DT_vec
:
DT_vec =
2008 7 21 0 0 0
2008 7 22 0 0 0
2008 7 23 0 0 0
2008 7 29 0 0 0
2008 8 4 0 0 0
2008 8 12 0 0 0
2008 9 14 0 0 0
2008 9 15 0 0 0
2008 9 16 0 0 0
2008 9 17 0 0 0
2008 9 20 0 0 0
2008 9 21 0 0 0
存储在My_data
中的数据:
32
43
12
43
2
12
54
32
34
5
32
12
我想要计算此时间序列的每周(或每月)平均值(My_data
)。我怎么能这样做?
答案 0 :(得分:4)
每月更容易,您可以使用DT_vec
中的第一列和第二列来创建accumarray
所需的subs
数组
[~,~,subs] = unique(DT_vec(:,1:2), 'rows')
MonthlyMeans = accumarray(subs, My_data, [], @mean)
你可以每周做同样的事情,但是你必须弄清楚如何获得subs
。它不应该复杂得多,但使用日期序列号(即datenum(DT_vec)
)可能更容易,然后执行subs = floor((datenum(DT_vec) + offset)/7)
之类的操作,其中offset
是0
和6
之间的整数,用于获取周日(或周一)开始的数字。然后,您可能希望减去第一周的开始时间为1
subs = subs - min(subs) + 1
修改:这是如何运作的,offset
是什么?
这里的想法是将您的日期表示为serial numbers (by using the datenum
function)。来自datenum
的文档:
datenum函数创建一个数字数组,表示每个时间点为从0000年1月0日起的天数。
因此,datenum
的结果中的每个整数都代表一整天。在您的示例DT_vec
(即datenum(DT_vec)
)上运行此操作,我们得到:
DT_num =
733610
733611
733612
733618
733624
733632
733665
733666
733667
733668
733671
733672
您的前两个日期是连续的,因此DT_num(2) - DT_num(1) == 1
。那么我们如何找到周?我们需要将这些序列日期编号分组为7.为此,我将每个数字除以7
,然后使用floor
删除小数点。要使用较小的数字来证明这一点,当我们将0:14
除以7
时会发生什么?我们得到
0
0.1429
0.2857
0.4286
0.5714
0.7143
0.8571
1.0000
1.1429
1.2857
1.4286
1.5714
1.7143
1.8571
2.0000
如果我们使用楼层删除小数,我们得到:
0
0
0
0
0
0
0
1
1
1
1
1
1
1
2
您的实际数字也会出现同样的情况,他们只是从0
开始。那么偏移量是多少?好吧,因为在除以7
之后每个整数的变化代表一个新的星期,我们需要确保我们从周日开始划分周,而不是像星期四那样任意一天。由于MATLAB从1月1日开始计算,我们需要知道一周中的哪一天,然后使用offset
来使它好像从下一个星期日开始计算。什么日子是0000年1月1日?我们可以使用MATLAB的weekday
函数来查找。例如今天是星期几?
weekday(datenum([2016 03 14]))
返回2
表示星期一。那天是哪一天0
? weekday(0)
返回6
表示星期五。因此,我们需要抵消此计数器,使其从0
开始,因此offset
应该等于weekday(1) - 1
。
为了进一步说明这一点,请考虑过去14天:
d = (today-7:today)'
现在
[floor(d/7) weekday(d)]
返回
ans =
105198 2
105198 3
105198 4
105198 5
105199 6
105199 7
105199 1
105199 2
105199 3
105199 4
105199 5
105200 6
105200 7
105200 1
105200 2
当第二列从7
转到1
时,新的一周开始,但您可以看到第1列中由floor(d/7)
创建的分组与此不对应。事实上它已被5
(或-2
)关闭。这就是我们想要使用offset
的内容。因此,如果我们设置offset = weekday(0) - 1
,那么
[floor((d+offset)/7) weekday(d)]
给出
105199 2
105199 3
105199 4
105199 5
105199 6
105199 7
105200 1
105200 2
105200 3
105200 4
105200 5
105200 6
105200 7
105201 1
105201 2
正确划分周数。