【问题标题】:How to resample time vector data matlab如何重采样时间向量数据matlab
【发布时间】:2013-08-09 09:21:21
【问题描述】:

我必须重新采样以下元胞数组:

dateS = 

'2004-09-02 06:00:00'
'2004-09-02 07:30:00'
'2004-09-02 12:00:00'
'2004-09-02 18:00:00'
'2004-09-02 19:30:00'
'2004-09-03 00:00:00'
'2004-09-03 05:30:00'
'2004-09-03 06:00:00'

遵循不规则的间距,例如第 1 行和第 2 行之间有 5 个读数,而第 2 和第 3 行之间有 10 个。中间“读数”的数量存储在向量“v”中。所以,我需要的是一个新向量,其中所有中间日期/时间在 dateS 处采用相同格式。

编辑:

列表中的前 2 个读数之间有 1 小时 30 分钟 = 90 分钟。五个间隔 b/w 等于 90 分钟 / 5 = 18 分钟。现在在 (1) 和 (2) 之间插入五个“读数”,每个读数间隔 18 分钟。我需要在所有日期都这样做。

有什么想法吗?谢谢!

【问题讨论】:

    标签: matlab time-series interpolation


    【解决方案1】:

    您可以使用interp1() 插入序列日期:

    % Inputs
    dates = [
    '2004-09-02 06:00:00'
    '2004-09-02 07:30:00'
    '2004-09-02 12:00:00'
    '2004-09-02 18:00:00'
    '2004-09-02 19:30:00'
    '2004-09-03 00:00:00'
    '2004-09-03 05:30:00'
    '2004-09-03 06:00:00'];
    
    v = [5 4 3 2 4 5 3];
    
    % Serial dates
    serdates  = datenum(dates,'yyyy-mm-dd HH:MM:SS');
    % Interpolate
    x         = cumsum([1 v]);
    resampled = interp1(x, serdates, x(1):x(end))';
    

    结果:

    datestr(resampled)
    ans =
    02-Sep-2004 06:00:00
    02-Sep-2004 06:18:00
    02-Sep-2004 06:36:00
    02-Sep-2004 06:54:00
    02-Sep-2004 07:12:00
    02-Sep-2004 07:30:00
    02-Sep-2004 08:37:30
    02-Sep-2004 09:45:00
    02-Sep-2004 10:52:30
    02-Sep-2004 12:00:00
    02-Sep-2004 14:00:00
    02-Sep-2004 16:00:00
    02-Sep-2004 18:00:00
    02-Sep-2004 18:45:00
    02-Sep-2004 19:30:00
    02-Sep-2004 20:37:30
    02-Sep-2004 21:45:00
    02-Sep-2004 22:52:30
    03-Sep-2004 00:00:00
    03-Sep-2004 01:06:00
    03-Sep-2004 02:12:00
    03-Sep-2004 03:18:00
    03-Sep-2004 04:24:00
    03-Sep-2004 05:30:00
    03-Sep-2004 05:40:00
    03-Sep-2004 05:50:00
    03-Sep-2004 06:00:00
    

    【讨论】:

    • +1 非常巧妙地使用 interp1 - 不得不画一张图来向自己解释发生了什么......请注意,最近对问题的澄清,你并没有完全给出“正确”的答案...如果 v(1)=5,则需要 18 分钟的间隔。
    • @Floris:谢谢,错过了他的意思是 5 个周期而不是 5 个中间步骤。编辑了答案。
    • 没问题 - 我一开始就是这样,但后来他更新了问题。我注意到你复制了我最初的v 向量...这就是为什么我可以告诉你:-)
    【解决方案2】:

    以下代码可以满足您的需求(我为 v 选择了任意值 - 只要向量 v 中的元素数比 dateS 中的条目数少一,这应该可以工作):

    dateS = [
    '2004-09-02 06:00:00'
    '2004-09-02 07:30:00'
    '2004-09-02 12:00:00'
    '2004-09-02 18:00:00'
    '2004-09-02 19:30:00'
    '2004-09-03 00:00:00'
    '2004-09-03 05:30:00'
    '2004-09-03 06:00:00'];
    
    % "stations":
    v = [6 5 4 3 5 6 4];
    
    dn = datenum(dateS);
    
    df = diff(dn)'./v;
    
    newDates = [];
    for ii = 1:numel(v)
        newDates = [newDates dn(ii) + (0:v(ii))*df(ii)];
    end
    
    newStrings = datestr(newDates, 'yyyy-mm-dd HH:MM:SS');
    

    数组newStrings最终包含以下内容:例如,您可以看到第一次和第二次之间的时间间隔被分成了6个15分钟的片段

    2004-09-02 06:00:00
    2004-09-02 06:15:00
    2004-09-02 06:30:00
    2004-09-02 06:45:00
    2004-09-02 07:00:00
    2004-09-02 07:15:00
    2004-09-02 07:30:00
    2004-09-02 08:24:00
    2004-09-02 09:18:00
    2004-09-02 10:12:00
    2004-09-02 11:06:00
    2004-09-02 12:00:00
    2004-09-02 13:30:00
    2004-09-02 15:00:00
    2004-09-02 16:30:00
    2004-09-02 18:00:00
    2004-09-02 18:30:00
    2004-09-02 19:00:00
    2004-09-02 19:30:00
    2004-09-02 20:24:00
    2004-09-02 21:18:00
    2004-09-02 22:12:00
    2004-09-02 23:06:00
    2004-09-03 00:00:00
    2004-09-03 00:55:00
    2004-09-03 01:50:00
    2004-09-03 02:45:00
    2004-09-03 03:40:00
    2004-09-03 04:35:00
    2004-09-03 05:30:00
    2004-09-03 05:37:30
    2004-09-03 05:45:00
    2004-09-03 05:52:30
    

    代码依赖于几个概念:

    1. 日期可以表示为字符串或datenum。我使用内置函数在它们之间移动
    2. 将日期/时间作为数字后,很容易插值
    3. 我使用diff 函数来查找连续时间之间的差异
    4. 我不会尝试“矢量化”代码 - 您不是要求高效的代码,对于这样的示例,for 循环的清晰度胜过一切。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-28
      • 2018-05-27
      • 2020-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 1970-01-01
      相关资源
      最近更新 更多