如何通过匹配时间间隔来联接Matlab(2018)中的表?

时间:2018-10-09 11:35:09

标签: matlab timestamp time-series data-mining matlab-table

我有两个表A和B。我想根据它们的有效时间间隔将它们加入。

A在生产期间具有产品质量(不规则时间),B具有每小时设置。我需要创建一个像C一样的表,其中包含落入B的ValidFrom ValidTo时间范围内的所有A的RefDates的参数p1和p2。

A
RefDate                 result
'11-Oct-2017 00:14:00'  17
'11-Oct-2017 00:14:00'  19
'11-Oct-2017 00:20:00'  5
'11-Oct-2017 01:30:00'  25
'11-Oct-2017 01:30:00'  18
'11-Oct-2017 03:03:00'  28


B
ValidFrom               ValidTo                 p1  p2
'11-Oct-2017 00:13:00'  '11-Oct-2017 01:12:59'  2   1
'11-Oct-2017 01:13:00'  '11-Oct-2017 02:12:59'  3   1
'11-Oct-2017 02:13:00'  '11-Oct-2017 03:12:59'  4   5
'11-Oct-2017 03:13:00'  '11-Oct-2017 04:12:59'  6   1
'11-Oct-2017 04:13:00'  '11-Oct-2017 05:12:59'  7   9

我需要得到这样的东西。

C
RefDate                 res p1  p2
'11-Oct-2017 00:14:00'  17  2   1
'11-Oct-2017 00:14:00'  19  2   1
'11-Oct-2017 00:20:00'  5   2   1
'11-Oct-2017 01:30:00'  25  3   1
'11-Oct-2017 01:30:00'  18  3   1
'11-Oct-2017 03:03:00'  28  4   5

我知道如何在SQL中执行此操作,并且我想我已经弄清楚了如何在MatLab中逐行执行此操作,但这非常慢。数据集很大。我只是认为必须有一种我找不到的更优雅的方式。

导致我的许多方法失败的原因是RefDate列不是唯一的。

编辑: 实际表具有数千行和数百个变量。

C (in reality)
RefDate                 res res2 ... res200 p1  p2 ... p1000
11-Oct-2017 00:14:00    17                  2   1
11-Oct-2017 00:14:00    19                  2   1
11-Oct-2017 00:20:00    5                   2   1
11-Oct-2017 01:30:00    25                  3   1
11-Oct-2017 01:30:00    18                  3   1
11-Oct-2017 03:03:00    28                  4   5

2 个答案:

答案 0 :(得分:5)

实际上可以在一行代码中完成。假设您的ValidTo值总是紧接在下一行中的ValidFrom之前(在您的示例中就是这样),那么您只需要使用ValidFrom值即可。首先,使用datenum将这些值和您的RefDate值转换为序列号。然后使用discretize函数以RefDate值作为边对ValidFrom值进行装箱,这将为您提供B中的行索引,该索引包含每次{{ 1}}。然后使用该索引提取Ap1值并将它们附加到p2

A

以上解决方案适用于>> C = [A B(discretize(datenum(A.RefDate), datenum(B.ValidFrom)), 3:end)] C = RefDate result p1 p2 ______________________ ______ __ __ '11-Oct-2017 00:14:00' 17 2 1 '11-Oct-2017 00:14:00' 19 2 1 '11-Oct-2017 00:20:00' 5 2 1 '11-Oct-2017 01:30:00' 25 3 1 '11-Oct-2017 01:30:00' 18 3 1 '11-Oct-2017 03:03:00' 28 4 5 中任意数量的列pN

如果B中有任何时间不属于A中的任何范围,则必须将解决方案分成多行,以便可以检查索引是否从B返回的值包含discretize的值。假设您要从NaN中排除这些行,这将是新的解决方案:

C

答案 1 :(得分:2)

以下代码完全符合您的要求:

% convert to datetime
A.RefDate = datetime(A.RefDate);
B.ValidFrom = datetime(B.ValidFrom);
B.ValidTo = datetime(B.ValidTo);

% for each row in A, find the matching row in B
i = cellfun(@find, arrayfun(@(x) (x >= B.ValidFrom) & (x <= B.ValidTo), A.RefDate, 'UniformOutput', false), 'UniformOutput', false);

% find rows in A that where not matched
j = cellfun(@isempty, i, 'UniformOutput', false);

% build the result
C = [B(cell2mat(i),:) A(~cell2mat(j),:)];

% display output
C
相关问题