如何根据时间戳组合数据?

时间:2017-11-15 09:35:55

标签: matlab indexing sum timestamp benchmarking

我有一系列文本文件包含带有两个单独时间戳的数据,并希望找出给定时间内所有值的总和。这些文件可能具有不同的行数,但总是有三列:value timestamp1 timestamp2,其中包含

等条目
6.2 1 4 
4.3 2 9 
7.2 3 10 

1.2 2 3 
0.3 3 9 
0.1 5 12 

以下是输出形成方式的说明:

  1. 两个输入的时间戳统一为唯一值的向量(因此对于上面的示例{1,2,3}∪{2,3,5} -> {1,2,3,5}{4,9,10}∪{3,9,12} -> {3,4,9,10,12})。
  2. 对于每个唯一时间戳,从每个输入中选择一个数据点,以便:

    • 如果查询的时间戳低于最小的可用时间戳,则会获取第一个数据值。
    • 否则,将采用具有更低或相等时间戳的数据值。
  3. 将两个值相加,然后处理下一个唯一时间戳(如果可用)。

  4. 如果我使用timestamp1对上面的示例数据应用此算法,我会得到:

    7.4 1  %6.2+1.2
    5.5 2  %4.3+0.3
    7.5 3  %7.2+0.3
    7.3 5  %7.2+0.1 
    

    timestamp2

    7.4 3  %6.2+1.2
    7.4 4  %6.2+1.2
    4.6 9  %4.3+0.3
    7.5 10 %7.2+0.3
    7.3 12 %7.2+0.1
    

    我想我需要对time series做点什么,所以我已经有了以下转换器代码:

    logs = dir('log1/*.txt');
    k=1
    for log = logs' 
    
        t{k}=timeseries(load(log.name))
        k=k+1
    end
    

    我想下一步将是sum(t),但这不起作用。有人知道如何像上面那样结合它们吗?

    对于任何感兴趣的人,这些都是cpu和实时时间戳(自算法开始),用于测量算法的性能。

2 个答案:

答案 0 :(得分:2)

我一直在思考这个问题,最后提出了以下解决方案。虽然它在概念上与Steve's answer没有区别,但至少它的矢量化了:)

%% Preparations:
%{
In the same folder:

data1.txt:
6.2 1 4
4.3 2 9
7.2 3 10

data2.txt:
1.2 2 3
0.3 3 9
0.1 5 12
%}

function out = q47303825(fname1,fname2,whichStamp)
%% Input handling:
if nargin < 3
  whichStamp = 1;
end
if nargin == 0
  fname1 = 'data1.txt';
  fname2 = 'data2.txt';
end
%% Reading the data :
d1 = dlmread(fname1,' ');
d2 = dlmread(fname2,' ');
%% Preallocation:
out = union(d1(:,whichStamp+1), d2(:,whichStamp+1)) .* [NaN,1];
%% Modifying the data slightly to allow vectorization:
d1 = [d1(1), -Inf, -Inf; d1; d1(size(d1,1)), +Inf, +Inf];
d2 = [d2(1), -Inf, -Inf; d2; d2(size(d2,1)), +Inf, +Inf];
%% Find indices:
[~,I1] = min(d1(:,whichStamp+1) <= out(:,2).',[],1);
[~,I2] = min(d2(:,whichStamp+1) <= out(:,2).',[],1);
I1 = I1-1; I2 = I2-1;
%% Generate final output:
out(:,1) = d1(I1) + d2(I2);

答案 1 :(得分:1)

正如我所看到的,两个不同的时间戳是一个红色的鲱鱼 - 您可以为一个时间戳定义您的问题,忽略另一个时间戳。

据我所知,你想:

  • 考虑两个数据集中出现的所有时间(此处,仅考虑 timestamp1 [1,2,3,5]
  • 使用最近邻居对两个列表中的任何缺失数据点进行插值/外推:(第一个数据集中缺少5,第二个数据集中缺少1
  • 返回填充缺失点的值的总和。

如果没有阅读操作,我就会看到您的处理方式:

times1 = [1,2,3];
values1 = [6.2, 4.3, 7.2];

times2 = [2, 3, 5];
values2 = [1.2, 0.3, 0.1];

all_times = union(times1, times2)';
values1_interp = interp1(times1, values1, all_times, 'nearest', 'extrap');
values2_interp = interp1(times2, values2, all_times, 'nearest', 'extrap');
v_sum = values1_interp + values2_interp;

可以看到结果:

>> table(v_sum, all_times)

ans = 

    v_sum    all_times
    _____    _________

    7.4      1        
    5.5      2        
    7.5      3        
    7.3      5     

如果我们使用

times1 = [4, 9, 10];
times2 = [3, 9, 12];

然后我们会得到

>> table(v_sum, all_times)

ans = 

    v_sum    all_times
    _____    _________

    7.4       3       
    7.4       4       
    4.6       9       
    7.5      10       
    7.3      12  

修改:从OP's comment,我们不太想要最近的邻居,而是最近的邻居,但我们使用第一个如果我们在时间开始之前推断一段时间(例如,当我们的values11时将times1推断到时间[2,3,4]),请指出:为此您可以使用类似的东西

function [vq] = interp_left(x, v, xq)
%INTERP_LEFT Interpolate to the left-nearest point
% x must be sorted.
vq = nan(size(xq));
for ii = 1:length(xq)
  % Find the index in x nearest to xq, only considering smaller x
  [~,jj] = max(x(x<=xq(ii)));
  % Special case, there are no smaller x; extrapolate using [x(1),v(1)]
  if isempty(jj)
    vq(ii) = v(1);
  else
    vq(ii) = v(jj);
  end % if
end % for
end % function

然后用

times1 = [1,2,3];
values1 = [6.2, 4.3, 7.2];

times2 = [2, 3, 5];
values2 = [1.2, 0.3, 0.1];

all_times = union(times1, times2)';
values1_interp = interp_left(times1, values1, all_times);
values2_interp = interp_left(times2, values2, all_times);
v_sum = values1_interp + values2_interp;