如何在Matlab(2018)中通过匹配时间间隔连接表?

如何在Matlab(2018)中通过匹配时间间隔连接表?,matlab,timestamp,time-series,data-mining,matlab-table,Matlab,Timestamp,Time Series,Data Mining,Matlab Table,我有两个表A和B。我想根据它们的有效时间间隔将它们连接起来 A有产品质量(不定期),B有生产期间的小时设置。我需要创建一个类似于C的表,其中包含所有a的RefDates的参数p1和p2,这些参数都在B的ValidFrom ValidTo时间范围内 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

我有两个表A和B。我想根据它们的有效时间间隔将它们连接起来

A有产品质量(不定期),B有生产期间的小时设置。我需要创建一个类似于C的表,其中包含所有a的RefDates的参数p1和p2,这些参数都在B的ValidFrom ValidTo时间范围内

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

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

% 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
%转换为日期时间
A.RefDate=日期时间(A.RefDate);
B.ValidFrom=日期时间(B.ValidFrom);
B.ValidTo=日期时间(B.ValidTo);
%对于A中的每一行,在B中查找匹配的行

i=cellfun(@find,arrayfun(@(x)(x>=B.ValidFrom)&(x这实际上可以在一行代码中完成。假设您的
ValidTo
值总是在下一行的
ValidFrom
之前结束(在您的示例中就是这样),您只需要使用
ValidFrom
值。首先,使用将这些值和
RefDate
值转换为序列日期号。然后使用该函数将
RefDate
值作为边存储
RefDate
值,这将为您提供
B
中包含
A
。然后使用该索引提取
p1
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 
上述解决方案适用于
B
中任意数量的列
pN

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

index = discretize(datenum(A.RefDate), datenum(B.ValidFrom));
C = [A(~isnan(index), :) B(index(~isnan(index)), 3:end)];

谢谢。这有一些方面可以改进我目前的方法,但有数百个p1、p2列,所以单独的方法不起作用。希望这能有所帮助(R2018b):我查看了文档。但我没有发现SQL中类似ON的功能。在SQL中,我可以更详细地指定键。我正在寻找类似的功能。这可能是Matlab中不存在的。@Schae:我明白你的意思。即使我没有找到连接两个表的“本机”解决方案,我也更新了代码以解决此问题。@Schae:我明白你的意思。即使我没有找到连接两个表的“本机”解决方案,我也更新了代码以解决此问题我们的问题更加普遍:现在唯一的必填列是
a.RefDate
B.ValidFrom
,和
B.ValidTo
。以上(nice)如果
a
中的
RefDate
B
中找不到匹配项,则代码将失败。非常感谢您的回答。我甚至没有想到
datenum
。这一点在我解决NaN问题时就起了作用。我现在看到的问题也已由您解决。您的解决方案比我提出的解决方案要优雅得多。