我通常需要总结具有给定聚合函数的不规则定时的时间序列(即,总和,平均等).但是,我现有的解决方案似乎效率低,速度慢.
采取聚合功能:
function aggArray = aggregate(array, groupIndex, collapseFn)
groups = unique(groupIndex, 'rows');
aggArray = nan(size(groups, 1), size(array, 2));
for iGr = 1:size(groups,1)
grIdx = all(groupIndex == repmat(groups(iGr,:), [size(groupIndex,1), 1]), 2);
for iSer = 1:size(array, 2)
aggArray(iGr,iSer) = collapseFn(array(grIdx,iSer));
end
end
end
请注意,array和groupIndex都可以是2D.数组中的每一列都是要聚合的独立系列,但groupIndex的列应合在一起(作为一行)以指定句点.
然后当我们给它带来一个不规则的时间序列时(注意第二个周期是一个基本周期更长),时间结果很差:
a = rand(20006,10);
b = transpose([ones(1,5) 2*ones(1,6) sort(repmat((3:4001), [1 5]))]);
tic; aggregate(a, b, @sum); toc
Elapsed time is 1.370001 seconds.
使用分析器,我们可以发现grpIdx线占执行时间的大约1/4(.28 s),iSer循环大约需要3/4(1.17 s)的总时间(1.48 s).
将此与期间无关紧要的情况进行比较:
tic; cumsum(a); toc
Elapsed time is 0.000930 seconds.
有没有更有效的方法来聚合这些数据?
时间安排结果
将每个响应放在一个单独的函数中,下面是我使用Intel i7在Windows 7上使用Matlab 2015b获得的时间结果:
original | 1.32451
felix1 | 0.35446
felix2 | 0.16432
divakar1 | 0.41905
divakar2 | 0.30509
divakar3 | 0.16738
matthewGunn1 | 0.02678
matthewGunn2 | 0.01977
关于groupIndex的澄清
2D groupIndex的一个示例是为1980 – 2015年的一组日常数据指定年份编号和周数:
a2 = rand(36*52*5, 10);
b2 = [sort(repmat(1980:2015, [1 52*5]))' repmat(1:52, [1 36*5])'];
因此,“年 – 周”时段由一行groupIndex唯一标识.这可以通过调用unique(groupIndex,’rows’)并获取第三个输出来有效地处理,因此可以随意忽略这部分问题.