清理包含缺失、重复或不均匀时间的时间表
此示例说明如何根据包含缺失、重复或不均匀时间的时间表来创建规则时间表。时间表是一种表类型,用于将时间戳或行时间与每一行数据进行关联。在规则时间表中,行时间会进行排序并且是唯一的,彼此相差相同的规则时间步。
此外,一些工具箱提供的函数能够处理数值数组形式的等间距时间序列数据。该示例还说明如何导出时间表中的数据以供其他函数使用。
有许多行时间问题会使时间表变得不规则。行时间可能缺失。它们可能次序混乱。它们可能重复,从而造成具有相同时间的多个行,这些行可能具有相同或不同数据。即使它们存在、已排序且唯一,也会因不同大小的时间步而异。
时间表提供了很多种不同的方式来解决时间缺失、重复或不均匀的问题,以及对数据进行重采样或将数据聚合以创建规则行时间。

加载时间表
从 MAT 文件 badTimes 加载一个样本时间表,其中包含在 2016 年 6 月 9 日的几个小时内获取的天气测量值。时间表 TT 包含在当天不定时获取的温度、降雨量和风速测量值。
load badTimes
TTTT=12×3 timetable
Time Temp Rain WindSpeed
____________________ ____ ____ _________
09-Jun-2016 06:01:04 73 0.01 2.3
09-Jun-2016 07:59:23 59 0.08 0.9
09-Jun-2016 09:53:57 59 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
NaT 56 0 0
09-Jun-2016 09:53:57 67 0.03 3.4
09-Jun-2016 08:49:10 62 0.01 2.7
09-Jun-2016 08:49:10 75.8 0.01 2.7
09-Jun-2016 08:49:10 82 0.01 2.7
09-Jun-2016 05:03:11 66.2 0.05 3
09-Jun-2016 08:49:10 67.2 0.01 2.7
09-Jun-2016 04:12:00 58.8 NaN NaN
查找并删除缺失行时间的行
一种方法是首先查找并删除行时间为 NaT 或缺失值的行。要查找行时间向量中的缺失值,请使用 ismissing。ismissing 函数返回一个逻辑向量,只要 TT.Time 具有缺失值,该向量即包含 1。
natRowTimes = ismissing(TT.Time)
natRowTimes = 12×1 logical array
0
0
0
0
1
0
0
0
0
0
0
0
⋮
要仅保留未将缺失值作为行时间的行,请使用 ~natRowTimes 对 TT 进行索引。将这些行赋给新时间表 goodRowTimesTT。
goodRowTimesTT = TT(~natRowTimes,:)
goodRowTimesTT=11×3 timetable
Time Temp Rain WindSpeed
____________________ ____ ____ _________
09-Jun-2016 06:01:04 73 0.01 2.3
09-Jun-2016 07:59:23 59 0.08 0.9
09-Jun-2016 09:53:57 59 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
09-Jun-2016 08:49:10 62 0.01 2.7
09-Jun-2016 08:49:10 75.8 0.01 2.7
09-Jun-2016 08:49:10 82 0.01 2.7
09-Jun-2016 05:03:11 66.2 0.05 3
09-Jun-2016 08:49:10 67.2 0.01 2.7
09-Jun-2016 04:12:00 58.8 NaN NaN
此方法只会删除包含缺失的行时间的行。时间表变量仍可能包含缺失数据值。例如,对于 Rain 和 Windspeed 变量,goodRowTimesTT 的最后一行包含 NaN 值。
删除包含缺失时间和缺失数据的行
您也可以使用 rmmissing 函数同时删除缺失行时间和缺失数据值。rmmissing 删除任何包含缺失行时间、缺失数据值或同时包含两者的时间表行。
显示 TT 中缺失的行时间和缺失的数据值。
TT
TT=12×3 timetable
Time Temp Rain WindSpeed
____________________ ____ ____ _________
09-Jun-2016 06:01:04 73 0.01 2.3
09-Jun-2016 07:59:23 59 0.08 0.9
09-Jun-2016 09:53:57 59 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
NaT 56 0 0
09-Jun-2016 09:53:57 67 0.03 3.4
09-Jun-2016 08:49:10 62 0.01 2.7
09-Jun-2016 08:49:10 75.8 0.01 2.7
09-Jun-2016 08:49:10 82 0.01 2.7
09-Jun-2016 05:03:11 66.2 0.05 3
09-Jun-2016 08:49:10 67.2 0.01 2.7
09-Jun-2016 04:12:00 58.8 NaN NaN
删除所有包含缺失的行时间或数据值的行。将其余行赋给时间表 goodValuesTT。
goodValuesTT = rmmissing(TT)
goodValuesTT=10×3 timetable
Time Temp Rain WindSpeed
____________________ ____ ____ _________
09-Jun-2016 06:01:04 73 0.01 2.3
09-Jun-2016 07:59:23 59 0.08 0.9
09-Jun-2016 09:53:57 59 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
09-Jun-2016 08:49:10 62 0.01 2.7
09-Jun-2016 08:49:10 75.8 0.01 2.7
09-Jun-2016 08:49:10 82 0.01 2.7
09-Jun-2016 05:03:11 66.2 0.05 3
09-Jun-2016 08:49:10 67.2 0.01 2.7
对时间表进行排序并确定它是否为规则时间表
在处理缺失值后,您可以继续对时间表进行排序,然后确定排序后的时间表是否为规则时间表。
要确定 goodValuesTT 是否已排序,请使用 issorted 函数。
tf = issorted(goodValuesTT)
tf = logical
0
由于时间表未排序,请使用 sortrows 函数根据行时间对它进行排序。
sortedTT = sortrows(goodValuesTT)
sortedTT=10×3 timetable
Time Temp Rain WindSpeed
____________________ ____ ____ _________
09-Jun-2016 05:03:11 66.2 0.05 3
09-Jun-2016 06:01:04 73 0.01 2.3
09-Jun-2016 07:59:23 59 0.08 0.9
09-Jun-2016 08:49:10 62 0.01 2.7
09-Jun-2016 08:49:10 75.8 0.01 2.7
09-Jun-2016 08:49:10 82 0.01 2.7
09-Jun-2016 08:49:10 67.2 0.01 2.7
09-Jun-2016 09:53:57 59 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
确定 sortedTT 是否为规则时间表。规则时间表的连续行时间之间具有相同的时间间隔。即使是已排序的时间表,也可能具有不均匀的时间步。
tf = isregular(sortedTT)
tf = logical
0
由于它不是规则时间表,会显示行时间之间的差。
diff(sortedTT.Time)
ans = 9×1 duration
00:57:53
01:58:19
00:49:47
00:00:00
00:00:00
00:00:00
01:04:47
00:00:00
00:00:00
由于行时间经过排序,此结果显示有些行时间是唯一的,有些是重复的。
删除重复的行
时间表可以包含重复的行。如果多个时间表行具有相同的行时间和相同的数据值,则这些时间表行是重复的。在此示例中,sortedTT 的最后两行为重复行。(sortedTT 中有其他行具有重复的行时间,但数据值不同。)
要从 sortedTT 中删除重复行,请使用 unique。unique 函数会返回唯一行,并按行时间对这些行进行排序。
uniqueRowsTT = unique(sortedTT)
uniqueRowsTT=9×3 timetable
Time Temp Rain WindSpeed
____________________ ____ ____ _________
09-Jun-2016 05:03:11 66.2 0.05 3
09-Jun-2016 06:01:04 73 0.01 2.3
09-Jun-2016 07:59:23 59 0.08 0.9
09-Jun-2016 08:49:10 62 0.01 2.7
09-Jun-2016 08:49:10 67.2 0.01 2.7
09-Jun-2016 08:49:10 75.8 0.01 2.7
09-Jun-2016 08:49:10 82 0.01 2.7
09-Jun-2016 09:53:57 59 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
查找包含重复时间和不同数据的行
时间表可以具有行时间重复但数据值不同的行。在此示例中,uniqueRowsTT 有几行的行时间相同但值不同。
查找包含重复的行时间的行。首先,对行时间进行排序并查找其间没有差异的连续时间。其间没有差异的时间为重复的时间。对行时间向量进行向后索引,并返回一组标识 uniqueRowsTT 中的重复行时间的唯一时间。
dupTimes = sort(uniqueRowsTT.Time); tf = (diff(dupTimes) == 0); dupTimes = dupTimes(tf); dupTimes = unique(dupTimes)
dupTimes = 2×1 datetime
09-Jun-2016 08:49:10
09-Jun-2016 09:53:57
要显示具有重复行时间的行,请使用 dupTimes 对 uniqueRowsTT 进行索引。当您对时间进行索引时,输出时间表中会包含具有匹配的行时间的所有行。
uniqueRowsTT(dupTimes,:)
ans=6×3 timetable
Time Temp Rain WindSpeed
____________________ ____ ____ _________
09-Jun-2016 08:49:10 62 0.01 2.7
09-Jun-2016 08:49:10 67.2 0.01 2.7
09-Jun-2016 08:49:10 75.8 0.01 2.7
09-Jun-2016 08:49:10 82 0.01 2.7
09-Jun-2016 09:53:57 59 0.03 3.4
09-Jun-2016 09:53:57 67 0.03 3.4
选择包含重复时间的第一行和最后一行
当时间表中包含具有重复时间的行时,您可能希望选择特定的行,并丢弃具有重复时间的其他行。例如,您可以使用 unique 和 retime 函数来选择具有重复行时间的第一行或最后一行。
首先,通过使用 unique 从 TT 创建一个包含唯一行时间的向量。
uniqueTimes = unique(uniqueRowsTT.Time)
uniqueTimes = 5×1 datetime
09-Jun-2016 05:03:11
09-Jun-2016 06:01:04
09-Jun-2016 07:59:23
09-Jun-2016 08:49:10
09-Jun-2016 09:53:57
从包含重复时间的每一组行中选择第一行。要从第一行复制数据,请指定 'firstvalue' 方法。
firstUniqueRowsTT = retime(uniqueRowsTT,uniqueTimes,'firstvalue')firstUniqueRowsTT=5×3 timetable
Time Temp Rain WindSpeed
____________________ ____ ____ _________
09-Jun-2016 05:03:11 66.2 0.05 3
09-Jun-2016 06:01:04 73 0.01 2.3
09-Jun-2016 07:59:23 59 0.08 0.9
09-Jun-2016 08:49:10 62 0.01 2.7
09-Jun-2016 09:53:57 59 0.03 3.4
从包含重复时间的每一组行中选择最后一行。要从最后几行复制数据,请指定 'lastvalue' 方法。
lastUniqueRowsTT = retime(uniqueRowsTT,uniqueTimes,'lastvalue')lastUniqueRowsTT=5×3 timetable
Time Temp Rain WindSpeed
____________________ ____ ____ _________
09-Jun-2016 05:03:11 66.2 0.05 3
09-Jun-2016 06:01:04 73 0.01 2.3
09-Jun-2016 07:59:23 59 0.08 0.9
09-Jun-2016 08:49:10 82 0.01 2.7
09-Jun-2016 09:53:57 67 0.03 3.4
因此,firstUniqueRowsTT 和 lastUniqueRowsTT 的最后两行在 Temp 变量中具有不同值。
聚合包含重复时间的所有行中的数据
处理具有重复时间的行中的数据的另一种方法是以某种方式聚合或组合数据值。例如,您可以计算同时获取的具有相同数量的多个测量值的均值。
使用 retime 函数计算包含重复行时间的行的平均温度、降雨量和风速。
meanTT = retime(uniqueRowsTT,uniqueTimes,'mean')meanTT=5×3 timetable
Time Temp Rain WindSpeed
____________________ _____ ____ _________
09-Jun-2016 05:03:11 66.2 0.05 3
09-Jun-2016 06:01:04 73 0.01 2.3
09-Jun-2016 07:59:23 59 0.08 0.9
09-Jun-2016 08:49:10 71.75 0.01 2.7
09-Jun-2016 09:53:57 63 0.03 3.4
因此,meanTT 的最后两行的 Temp 变量的值为具有重复行时间的行的平均温度。
创建规则时间表
最后,您可以使用 retime 函数对不规则时间表中的数据进行重采样,使其变得规则。例如,您可以对 meanTT 中数据进行插值以创建一个按小时计的规则时间向量中。要使用线性插值,请指定 'linear'。hourlyTT 中的每个行时间都从整点时刻开始,并且连续的行时间之间的间隔为一小时。
hourlyTT = retime(meanTT,'hourly','linear')
hourlyTT=6×3 timetable
Time Temp Rain WindSpeed
____________________ ______ ________ _________
09-Jun-2016 05:00:00 65.826 0.0522 3.0385
09-Jun-2016 06:00:00 72.875 0.010737 2.3129
09-Jun-2016 07:00:00 66.027 0.044867 1.6027
09-Jun-2016 08:00:00 59.158 0.079133 0.9223
09-Jun-2016 09:00:00 70.287 0.013344 2.8171
09-Jun-2016 10:00:00 62.183 0.031868 3.4654
您可以指定自己的时间步,而不是使用诸如 'hourly' 等预定义的时间步。要指定 30 分钟的时间步,请使用 'regular' 输入参量和 'TimeStep' 名称-值参量。您可以将任意大小的时间步指定为 duration 或 calendarDuration 值。
regularTT = retime(meanTT,'regular','linear','TimeStep',minutes(30))
regularTT=11×3 timetable
Time Temp Rain WindSpeed
____________________ ______ ________ _________
09-Jun-2016 05:00:00 65.826 0.0522 3.0385
09-Jun-2016 05:30:00 69.35 0.031468 2.6757
09-Jun-2016 06:00:00 72.875 0.010737 2.3129
09-Jun-2016 06:30:00 69.576 0.027118 1.9576
09-Jun-2016 07:00:00 66.027 0.044867 1.6027
09-Jun-2016 07:30:00 62.477 0.062616 1.2477
09-Jun-2016 08:00:00 59.158 0.079133 0.9223
09-Jun-2016 08:30:00 66.841 0.03695 2.007
09-Jun-2016 09:00:00 70.287 0.013344 2.8171
09-Jun-2016 09:30:00 66.235 0.022606 3.1412
09-Jun-2016 10:00:00 62.183 0.031868 3.4654
将规则时间表数据提取到数组中
您可以导出时间表数据供函数使用,以分析具有固定时间间隔的数据。例如,Econometrics Toolbox™ 和 Signal Processing Toolbox™ 带有可用于进一步分析等间距数据的函数。
提取时间表数据作为数组。您可以使用 Variables 属性将数据作为数组返回,只要表变量的数据类型允许它们串联在一起。
A = regularTT.Variables
A = 11×3
65.8260 0.0522 3.0385
69.3504 0.0315 2.6757
72.8747 0.0107 2.3129
69.5764 0.0271 1.9576
66.0266 0.0449 1.6027
62.4768 0.0626 1.2477
59.1579 0.0791 0.9223
66.8412 0.0370 2.0070
70.2868 0.0133 2.8171
66.2348 0.0226 3.1412
62.1829 0.0319 3.4654
⋮
regularTT.Variables 等效于使用花括号语法 regularTT{:,:} 访问时间表变量中的数据。
A2 = regularTT{:,:}A2 = 11×3
65.8260 0.0522 3.0385
69.3504 0.0315 2.6757
72.8747 0.0107 2.3129
69.5764 0.0271 1.9576
66.0266 0.0449 1.6027
62.4768 0.0626 1.2477
59.1579 0.0791 0.9223
66.8412 0.0370 2.0070
70.2868 0.0133 2.8171
66.2348 0.0226 3.1412
62.1829 0.0319 3.4654
⋮
另请参阅
timetable | table2timetable | retime | issorted | sortrows | unique | diff | isregular | rmmissing | fillmissing