【问题标题】:Populate missing timestamp data rows with NAN - MATLAB使用 NAN 填充缺失的时间戳数据行 - MATLAB
【发布时间】:2017-05-12 21:00:27
【问题描述】:

我有一个数据集缺少一些时间戳。到目前为止,我已经编写了以下代码,

x = table2dataset(Testing_data);
T1 = x(:,1);              
C1 =dataset2cell(T1);
formatIn = 'yyyy-mm-dd HH:MM:SS';
t1= datenum(C1,formatIn);

% Creating 10 minutes of time interval;
avg = 10/60/24;        
tnew = [t1(1):avg:t1(end)]';
indx = round((t1-t1(1))/avg) + 1;
ynew = NaN(length(tnew),1);
ynew(indx)=t1;

% replacing missing time with NaN
t = datetime(ynew,'ConvertFrom','datenum');                 
formatIn = 'yyyy-mm-dd HH:MM:SS';
DateVector = datevec(ynew,formatIn);
dt = datestr(ynew,'yyyy-mm-dd HH:MM:SS');
ds = string(dt);

这里显示的测试数据有三个参数,

     Time                       x          y
2009-04-10 02:00:00.000         1         0.1
2009-04-10 02:10:00.000         2         0.2
2009-04-10 02:30:00.000         3         0.3
2009-04-10 02:50:00.000         4         0.4

现在您可以看到,对于 10 分钟的间隔,缺少时间戳(2:20 和 2:40),所以我想添加那个时间戳。然后我希望xy 的值是NAN。所以我的输出是这样的,

       Time                     x          y
2009-04-10 02:00:00.000         1         0.1
2009-04-10 02:10:00.000         2         0.2
2009-04-10 02:20:00.000         NaN       NaN
2009-04-10 02:30:00.000         3         0.3    
2009-04-10 02:40:00.000         NaN       NaN
2009-04-10 02:50:00.000         4         0.4

正如您从我的代码中看到的那样,我只能添加带有时间戳的NaN,但现在想获取我想要的对应的 x 和 y 值。

请注意,我有超过 3000 个上述格式的数据行,我想对我的所有值执行相同的操作。

【问题讨论】:

    标签: arrays matlab timestamp time-series


    【解决方案1】:

    您的问题似乎自相矛盾;你说你可以插入NaN 来代替丢失的时间字符串,但是在预期输出的例子中你写了时间字符串。

    您还提到缺少时间戳 (2:20),但如果时间步长为 10 分钟,则在您的示例数据中还有另一个缺少时间戳 (2:40)

    假设:

    • 您实际上想要插入缺少的时间刺
    • 您想管理所有缺失的时间戳

    你可以修改你的代码如下:

    • 不需要ynew 时间
    • 应该使用tnew 时间代替ynew
    • 要在xy 列中插入NaN 值,您必须:
      • dataset 中提取它们
      • 创建两个新数组,将它们初始化为NaN
      • indx标识的位置插入原始xy数据

    在下面你可以找到你的代码的更新版本。

    • xy 数据存储在 x_datay_data 数组中
    • 新的xy 数据存储在x_data_newy_data_new 数组中

    在脚本的最后,生成了两个表:第一个是使用时间生成的string,第二个是cellarray。

    代码中的 cmets 应该识别修改。

    x = table2dataset(Testing_data);
    T1 = x(:,1);
    % Get X data from the table
    x_data=x(:,2)
    % Get Y data from the table
    y_data=x(:,3)
    
    C1 =dataset2cell(T1);
    
    formatIn = 'yyyy-mm-dd HH:MM:SS';
    t1= datenum(C1(2:end),formatIn)
    
    avg = 10/60/24;        % Creating 10 minutes of time interval;
    tnew = [t1(1):avg:t1(end)]'
    indx = round((t1-t1(1))/avg) + 1
    %
    % Not Needed
    %
    % ynew = NaN(length(tnew),1);
    % ynew(indx)=t1;
    %
    % Create the new X and Y data
    %
    y_data_new = NaN(length(tnew),1)
    y_data_new(indx)=t1
    
    x_data_new=nan(length(tnew),1)
    x_data_new(indx)=x_data
    y_data_new=nan(length(tnew),1)
    y_data_new(indx)=y_data
    
    % t = datetime(ynew,'ConvertFrom','datenum')  % replacing missing time with NAN
    %
    % Use tnew instead of ynew
    %
    t = datetime(tnew,'ConvertFrom','datenum')  % replacing missing time with NAN
    formatIn = 'yyyy-mm-dd HH:MM:SS'
    % DateVector = datevec(y_data_new,formatIn)
    % dt = datestr(ynew,'yyyy-mm-dd HH:MM:SS')
    %
    % Use tnew instead of ynew
    %
    dt = datestr(tnew,'yyyy-mm-dd HH:MM:SS')
    % ds = char(dt)
    
    new_table=table(dt,x_data_new,y_data_new)
    new_table_1=table(cellstr(dt),x_data_new,y_data_new)
    

    输出是

    new_table = 
    
            dt         x_data_new    y_data_new
        ___________    __________    __________
    
        [1x19 char]      1           0.1       
        [1x19 char]      2           0.2       
        [1x19 char]    NaN           NaN       
        [1x19 char]      3           0.3       
        [1x19 char]    NaN           NaN       
        [1x19 char]      4           0.4       
    
    
    new_table_1 = 
    
                Var1             x_data_new    y_data_new
        _____________________    __________    __________
    
        '2009-04-10 02:00:00'      1           0.1       
        '2009-04-10 02:10:00'      2           0.2       
        '2009-04-10 02:20:00'    NaN           NaN       
        '2009-04-10 02:30:00'      3           0.3       
        '2009-04-10 02:40:00'    NaN           NaN       
        '2009-04-10 02:50:00'      4           0.4   
    

    希望这会有所帮助。

    卡普拉'

    【讨论】:

    • 谢谢你。我只是举了一个例子。它正在工作,但正如我之前所说,我的数据集包含 6 个参数(例如 x、y、z、a、b、c)。对于所有这 6 个参数,是否有任何更简单的方法(您对 x 和 y 所做的)相同。意味着每当缺少时间戳时,将 NAN 与其对应的 x 、 y、z、a、b、c ...??
    • 我不明白这个问题:你想将NaN设置为仅附加参数(z,a,b,c)还是设置时间戳?说:NaN-NaN-NaN ... NaN NaN NaN2009-04-10 02:40:00 NaN NaN NaN NaN NaN NaN?
    • 仅用于参数。你刚刚写的代码我想要参数而不是时间戳......
    • 例如 2009-04-10 02:40:00 NaN NaN NaN NaN NaN NaN
    • 我正在寻找更简单的代码而不是这么大的代码!!
    【解决方案2】:

    这个例子与公认的答案没有太大不同,但恕我直言,看起来更容易一些。但是,它支持大于 1 步的间隙,并且更通用一些,因为它做出的假设更少。

    它适用于普通元胞数组而不是原始表数据,因此转换取决于您(我在 R2010a 上,所以无法测试)

    % Example data with intentional gaps of varying size
    old_data = {'2009-04-10 02:00:00.000'  1   0.1
                '2009-04-10 02:10:00.000'  2   0.2
                '2009-04-10 02:30:00.000'  3   0.3
                '2009-04-10 02:50:00.000'  4   0.4
                '2009-04-10 03:10:00.000'  5   0.5
                '2009-04-10 03:20:00.000'  6   0.6
                '2009-04-10 03:50:00.000'  7   0.7}
    
    
    % Convert textual dates to numbers we can work with more easily
    old_dates = datenum(old_data(:,1));
    
    % Nominal step size is the minimum of all differences
    deltas = diff(old_dates);
    nominal_step = min(deltas);
    
    % Generate new date numbers with constant step
    new_dates = old_dates(1) : nominal_step : old_dates(end);
    
    % Determine where the gaps in the data are, and how big they are,
    % taking into account rounding error
    step_gaps = abs(deltas - nominal_step) > 10*eps;
    gap_sizes = round( deltas(step_gaps) / nominal_step - 1);
    
    % Create new data structure with constant-step time stamps, 
    % initially with the data of interest all-NAN
    new_size = size(old_data,1) + sum(gap_sizes);
    new_data = [cellstr( datestr(new_dates, 'yyyy-mm-dd HH:MM:SS') ),...
                repmat({NaN}, new_size, 2)];
    
    % Compute proper locations of the old data in the new data structure, 
    % again, taking into account rounding error
    day = 86400; % (seconds in a day)
    new_datapoint = ismember(round(new_dates * day), ...
                             round(old_dates * day));
    
    % Insert the old data at the right locations
    new_data(new_datapoint, 2:3) = data(:, 2:3)
    

    输出是:

    old_data = 
        '2009-04-10 02:00:00.000'    [1]    [0.100000000000000]
        '2009-04-10 02:10:00.000'    [2]    [0.200000000000000]
        '2009-04-10 02:30:00.000'    [3]    [0.300000000000000]
        '2009-04-10 02:50:00.000'    [4]    [0.400000000000000]
        '2009-04-10 03:10:00.000'    [5]    [0.500000000000000]
        '2009-04-10 03:20:00.000'    [6]    [0.600000000000000]
        '2009-04-10 03:50:00.000'    [7]    [0.700000000000000]
    
    new_data = 
        '2009-04-10 02:00:00'    [  1]    [0.100000000000000]
        '2009-04-10 02:10:00'    [  2]    [0.200000000000000]
        '2009-04-10 02:20:00'    [NaN]    [              NaN]
        '2009-04-10 02:30:00'    [  3]    [0.300000000000000]
        '2009-04-10 02:40:00'    [NaN]    [              NaN]
        '2009-04-10 02:50:00'    [  4]    [0.400000000000000]
        '2009-04-10 03:00:00'    [NaN]    [              NaN]
        '2009-04-10 03:10:00'    [  5]    [0.500000000000000]
        '2009-04-10 03:20:00'    [  6]    [0.600000000000000]
        '2009-04-10 03:30:00'    [NaN]    [              NaN]
        '2009-04-10 03:40:00'    [NaN]    [              NaN]
        '2009-04-10 03:50:00'    [  7]    [0.700000000000000]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-16
      • 2023-03-22
      • 2020-09-13
      • 1970-01-01
      相关资源
      最近更新 更多