1

这是我在此处发布的一个较早问题的后续行动。根据 Oleg Komarov 的回答,我编写了一个小工具来获取使用 accumarray() 和 datevec() 输出结构的数据的每日、每小时等平均值或总和。随意看看这里(它可能写得不太好,但它对我有用)。

我现在想做的是添加计算 n 分钟、n 小时、n 天等统计数据的功能,而不是像我的函数那样的 1 分钟、1 小时、1 天等。我有一个粗略的想法,就是简单地循环遍历我的时间向量 t(如果我没有了解漂亮的 accumarray(),这几乎是我已经做过的事情),但这意味着我必须做很多对数据间隙、不均匀采样时间等进行错误检查。

我想知道是否有一种更优雅/更有效的方法可以让我重新使用/扩展上面发布的旧函数,即仍然使用 accumarray() 和 datevec() 的方法,因为这使得处理间隙非常容易。

您可以在此处下载我上一个问题中的一些示例数据。这些以 30 分钟的间隔进行采样,因此我想要做的一个可能的例子是计算 6 小时的平均值,而不依赖于它们没有间隙和/或总是在 30 分钟采样的假设。


这是我迄今为止提出的,效果相当不错,除了时间戳的一个小但很容易解决的问题(例如,0:30 代表从 0:30 到 0:45 的时间间隔——我的老不过,函数也遇到了同样的问题):

[ ...请参阅下面的答案...]

感谢木片的启发。

4

2 回答 2

2

如果您从均匀间隔的测量开始,没有任何间隙,那么链接的使用方法accumarray对我来说似乎有点矫枉过正和过于复杂。我的私人工具箱中有以下函数用于计算向量的 N 点平均值:

function y = blockaver(x, n)
% y = blockaver(x, n)
% input points are averaged over n points
% always returns column vector

if n == 1
    y = x(:);
else
    nblocks = floor(length(x) / n);
    y = mean(reshape(x(1:n * nblocks), n, nblocks), 1).';
end

对于快速而肮脏的因子 N 抽取非常有效,但请注意,它没有应用适当的抗混叠过滤。decimate如果这很重要,请使用。

于 2013-08-04T18:53:53.883 回答
1

我想我是使用上面链接的@Bas Swinckels 答案的一部分和@woodchip 的代码弄明白的。不完全是我所说的好代码,但工作和相当快。

function [ t_acc, x_acc, subs ] = ts_aggregation( t, x, n, target_fmt, fct_handle )
% t is time in datenum format (i.e. days)
% x is whatever variable you want to aggregate
% n is the number of minutes, hours, days
% target_fmt is 'minute', 'hour' or 'day'
% fct_handle can be an arbitrary function (e.g. @sum)
    t = t(:);
    x = x(:);
    switch target_fmt
        case 'day'
            t_factor = 1;
        case 'hour'
            t_factor = 1 / 24;
        case 'minute'
            t_factor = 1 / ( 24 * 60 );
    end
    t_acc = ( t(1) : n * t_factor : t(end) )';
    subs = ones(length(t), 1);
    for i = 2:length(t_acc)
       subs(t > t_acc(i-1) & t <= t_acc(i)) = i; 
    end
    x_acc = accumarray( subs, x, [], fct_handle );
end

/edit:更新为使用循环的更短的功能,但似乎比我以前的解决方案更快。

于 2013-08-12T09:15:55.877 回答