如何根据时间戳组合数据?
How to combine data according to timestamps?
我有一系列包含具有两个独立时间戳的数据的文本文件,我想找出给定时间所有值的总和。这些文件可能有不同的行数,但总是三列: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,2,3}∪{2,3,5} -> {1,2,3,5}
或 {4,9,10}∪{3,9,12} -> {3,4,9,10,12}
)。
对于每个唯一的时间戳,从每个输入中选择一个数据点,使得:
- 如果查询的时间戳小于可用的最小时间戳,则取第一个数据值。
- 否则,取时间戳小于或等于的数据值。
将两个值相加并处理下一个唯一时间戳(如果可用)。
如果我使用 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 和实时时间戳(自算法开始以来),用于衡量算法的性能。
在我看来,两个不同的时间戳 是一个转移注意力的问题 - 您可以为一个时间戳定义问题,而忽略另一个。
据我了解,您想:
- 考虑出现在两个数据集中的所有时间(这里,只考虑timestamp1,是
[1,2,3,5]
)
- interpolate/extrapolate 对两个列表中的任何缺失数据点使用最近邻:(第一个数据集中缺少
5
,第二个数据集中缺少 1
)
- Return填充缺失点后的值之和
没有读取操作,我是这样看你的处理的:
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
编辑: 从 ,我们不太想要最近的邻居,而是 最近的邻居 ,但是如果我们在我们的时间开始之前外推时间,我们使用第一个点(例如,当我们的 times1
是 [2,3,4]
时,将 values1
外推到时间 1
:你可以使用类似
的东西
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;
这个问题我思考了很久,最后想出了下面的解决方案。虽然它在概念上与 没有区别,但至少它是矢量化的:)
%% 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);
我有一系列包含具有两个独立时间戳的数据的文本文件,我想找出给定时间所有值的总和。这些文件可能有不同的行数,但总是三列: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,2,3}∪{2,3,5} -> {1,2,3,5}
或{4,9,10}∪{3,9,12} -> {3,4,9,10,12}
)。 对于每个唯一的时间戳,从每个输入中选择一个数据点,使得:
- 如果查询的时间戳小于可用的最小时间戳,则取第一个数据值。
- 否则,取时间戳小于或等于的数据值。
将两个值相加并处理下一个唯一时间戳(如果可用)。
如果我使用 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 和实时时间戳(自算法开始以来),用于衡量算法的性能。
在我看来,两个不同的时间戳 是一个转移注意力的问题 - 您可以为一个时间戳定义问题,而忽略另一个。
据我了解,您想:
- 考虑出现在两个数据集中的所有时间(这里,只考虑timestamp1,是
[1,2,3,5]
) - interpolate/extrapolate 对两个列表中的任何缺失数据点使用最近邻:(第一个数据集中缺少
5
,第二个数据集中缺少1
) - Return填充缺失点后的值之和
没有读取操作,我是这样看你的处理的:
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
编辑: 从 times1
是 [2,3,4]
时,将 values1
外推到时间 1
:你可以使用类似
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;
这个问题我思考了很久,最后想出了下面的解决方案。虽然它在概念上与
%% 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);