时间基准系统 (TRS) 是用于标识时间的本地、区域或全球系统。
时间基准系统可以为时间戳记与相应数字表示之间的正向和逆向映射定义特定的投影。 大多数用户都很熟悉的一个常见示例是 UTC 时间,例如,它可以将时间戳记“1 Jan 2019, 12 midnight (GMT)”映射到 64 位整数值“1546300800000”,以捕获自“1 Jan 1970, 12 midnight (GMT)”以来经过的毫秒数。 一般而言,时间戳记值更适合人类读取,而数字表示更适合机器处理。
在时间序列库中,时间系列可以与一个 TRS 相关联。 TRS 由以下项组成:
- 用于捕获时间粒度的时钟节拍(例如,1 分钟)。
- 捕获开始时间的分区日期时间,例如
1 Jan 2019, 12 midnight US Eastern Daylight Savings time (EDT)
。 通过计算自开始时间以来经过的时间节拍数,可以将时间戳记映射到数字表示。 数字表示按粒度进行缩放,并在将其映射回时间戳记时按开始时间进行移位。
请注意,此“正向 + 逆向”投影可能导致时间损耗。 例如,如果时间序列的真实时间粒度以秒为单位,那么将时间戳记 09:00:01
和 09:00:02
(将读为 hh:mm:ss
) 的正向和反向映射到 1 分钟的粒度将分别生成时间戳记 09:00:00
和 09:00:00
。 在此示例中,粒度为秒的时间序列将映射到分钟,因此逆向映射会得到不准确的信息。 但是,如果映射的粒度高于输入时间序列的粒度(更具体来说,如果时间序列粒度是所映射粒度的整数倍),那么可保证“正向 + 逆向”投影无损耗。 例如,如果将粒度为分钟的时间序列映射到秒并将其逆向投影到分钟,那么将以无损耗的方式重构时间戳记。
设置 TRS
在创建时间序列时,它会与一个 TRS 相关联(如果未指定 TRS,那么它为“无”)。 如果 TRS 为“无”,那么数字值将无法映射到时间戳记。 请注意,只能在构造时对时间序列设置 TRS。 这是因为时间序列被设计为不可变对象。 在多线程环境或分布式计算环境(例如,Apache Spark)中使用库时,不变性就派上了用场。 虽然只能在构造时设置 TRS,但是可以使用 with_trs
方法(如下一部分中所述)对其进行更改。 with_trs
会生成一个新的时间序列,因此它不会影响不变性。
下面我们来看一个通过“内存中的列表”创建的简单时间序列:
values = [1.0, 2.0, 4.0]
x = tspy.time_series(values)
x
这将返回:
TimeStamp: 0 Value: 1.0
TimeStamp: 1 Value: 2.0
TimeStamp: 2 Value: 4.0
在构造时,会将时间序列与一个 TRS 相关联。 通过将 TRS 与时间序列相关联,可使数字时间戳记与时间节拍和偏移量/时区保持一致。 以下示例显示了 1 minute and 1 Jan 2019, 12 midnight (GMT)
:
zdt = datetime.datetime(2019,1,1,0,0,0,0,tzinfo=datetime.timezone.utc)
x_trs = tspy.time_series(data, granularity=datetime.timedelta(minutes=1), start_time=zdt)
x_trs
这将返回:
TimeStamp: 2019-01-01T00:00Z Value: 1.0
TimeStamp: 2019-01-01T00:01Z Value: 2.0
TimeStamp: 2019-01-01T00:02Z Value: 4.0
下面是另一个示例,其中使用时间节拍“1 小时”和偏移量/时区将数字时间戳记重新解释为 1 Jan 2019, 12 midnight US Eastern Daylight Savings time (EDT)
。
tz_edt = datetime.timezone.edt
zdt = datetime.datetime(2019,1,1,0,0,0,0,tzinfo=tz_edt)
x_trs = tspy.time_series(data, granularity=datetime.timedelta(hours=1), start_time=zdt)
x_trs
这将返回:
TimeStamp: 2019-01-01T00:00-04:00 Value: 1.0
TimeStamp: 2019-01-01T00:01-04:00 Value: 2.0
TimeStamp: 2019-01-01T00:02-04:00 Value: 4.0
请注意,时间戳记现在指示与 GMT 的偏移量 -4 小时(即,EDT 时区),并捕获时钟节拍“1 小时”。 另请注意,设置 TRS 并不会更改数字时间戳记,而只是指定数字时间戳记的解释方式。
x_trs.print(human_readable=False)
这将返回:
TimeStamp: 0 Value: 1.0
TimeStamp: 1 Value: 2.0
TimeStamp: 2 Value: 4.0
更改 TRS
您可以使用 with_trs
函数更改与时间序列相关联的 TRS。 请注意,如果输入时间序列未与 TRS 相关联(即 TRS 为“无”),那么此函数将抛出异常。 使用 with_trs
可更改数字时间戳记。
以下代码样本显示了在构造时设置的 TRS(而不是使用 with_trs
进行设置):
# 1546300800 is the epoch time in seconds for 1 Jan 2019, 12 midnight GMT
zdt1 = datetime.datetime(1970,1,1,0,0,0,0,tzinfo=datetime.timezone.utc)
y = tspy.observations.of(tspy.observation(1546300800, 1.0),tspy.observation(1546300860, 2.0), tspy.observation(1546300920,
4.0)).to_time_series(granularity=datetime.timedelta(seconds=1), start_time=zdt1)
y.print()
y.print(human_readable=False)
这将返回:
TimeStamp: 2019-01-01T00:00Z Value: 1.0
TimeStamp: 2019-01-01T00:01Z Value: 2.0
TimeStamp: 2019-01-01T00:02Z Value: 4.0
# TRS has been set during construction time - no changes to numeric timestamps
TimeStamp: 1546300800 Value: 1.0
TimeStamp: 1546300860 Value: 2.0
TimeStamp: 1546300920 Value: 4.0
以下示例显示如何应用 with_trs
以将 granularity
更改为 1 分钟并保留原始时间偏移量 (1 1970 年 1 月 12 日午夜 GMT):
y_minutely_1970 = y.with_trs(granularity=datetime.timedelta(minutes=1), start_time=zdt1)
y_minutely_1970.print()
y_minutely_1970.print(human_readable=False)
这将返回:
TimeStamp: 2019-01-01T00:00Z Value: 1.0
TimeStamp: 2019-01-01T00:01Z Value: 2.0
TimeStamp: 2019-01-01T00:02Z Value: 4.0
# numeric timestamps have changed to number of elapsed minutes since 1 Jan 1970, 12 midnight GMT
TimeStamp: 25771680 Value: 1.0
TimeStamp: 25771681 Value: 2.0
TimeStamp: 25771682 Value: 4.0
现在,应用 with_trs
以将 granularity
更改为 1 分钟,并将偏移量更改为 1 2019 年 1 月 12 日午夜 GMT:
zdt2 = datetime.datetime(2019,1,1,0,0,0,0,tzinfo=datetime.timezone.utc)
y_minutely = y.with_trs(granularity=datetime.timedelta(minutes=1), start_time=zdt2)
y_minutely.print()
y_minutely.print(human_readable=False)
这将返回:
TimeStamp: 2019-01-01T00:00Z Value: 1.0
TimeStamp: 2019-01-01T00:01Z Value: 2.0
TimeStamp: 2019-01-01T00:02Z Value: 4.0
# numeric timestamps are now minutes elapsed since 1 Jan 2019, 12 midnight GMT
TimeStamp: 0 Value: 1.0
TimeStamp: 1 Value: 2.0
TimeStamp: 2 Value: 4.0
为了更好地了解它如何影响后处理,我们来检查以下内容。 请注意,数字时间戳记上的 materialize
对与时间序列关联的底层数字时间戳记执行操作。
print(y.materialize(0,2))
print(y_minutely_1970.materialize(0,2))
print(y_minutely.materialize(0,2))
这将返回:
# numeric timestamps in y are in the range 1546300800, 1546300920 and thus y.materialize(0,2) is empty
[]
# numeric timestamps in y_minutely_1970 are in the range 25771680, 25771682 and thus y_minutely_1970.materialize(0,2) is empty
[]
# numeric timestamps in y_minutely are in the range 0, 2
[(0,1.0),(1,2.0),(2,4.0)]
方法 materialize
也可以应用于日期时间对象。 如果底层时间序列未与 TRS 相关联(即 TRS 为“无”),那么这将产生异常。 假定底层时间序列具有 TRS,那么将使用 TRS 将日期时间对象映射到数字范围。
# Jan 1 2019, 12 midnight GMT
dt_beg = datetime.datetime(2019,1,1,0,0,0,0,tzinfo=datetime.timezone.utc)
# Jan 1 2019, 12:02 AM GMT
dt_end = datetime.datetime(2019,1,1,0,2,0,0,tzinfo=datetime.timezone.utc)
print(y.materialize(dt_beg, dt_end))
print(y_minutely_1970.materialize(dt_beg, dt_end))
print(y_minutely.materialize(dt_beg, dt_end))
# materialize on y in UTC millis
[(1546300800,1.0),(1546300860,2.0), (1546300920,4.0)]
# materialize on y_minutely_1970 in UTC minutes
[(25771680,1.0),(25771681,2.0),(25771682,4.0)]
# materialize on y_minutely in minutes offset by 1 Jan 2019, 12 midnight
[(0,1.0),(1,2.0),(2,4.0)]
重复的时间戳记
更改 TRS 可能产生重复的时间戳记。 以下示例将粒度更改为一小时,这将导致重复的时间戳记。 时间序列库可以无缝地处理重复的时间戳记,并提供了一些便利组合器来将与重复时间戳记相关联的值减少至单个值,例如,通过计算按重复时间戳记分组的值的平均值。
y_hourly = y_minutely.with_trs(granularity=datetime.timedelta(hours=1), start_time=zdt2)
print(y_minutely)
print(y_minutely.materialize(0,2))
print(y_hourly)
print(y_hourly.materialize(0,0))
这将返回:
# y_minutely - minutely time series
TimeStamp: 2019-01-01T00:00Z Value: 1.0
TimeStamp: 2019-01-01T00:01Z Value: 2.0
TimeStamp: 2019-01-01T00:02Z Value: 4.0
# y_minutely has numeric timestamps 0, 1 and 2
[(0,1.0),(1,2.0),(2,4.0)]
# y_hourly - hourly time series has duplicate timestamps
TimeStamp: 2019-01-01T00:00Z Value: 1.0
TimeStamp: 2019-01-01T00:00Z Value: 2.0
TimeStamp: 2019-01-01T00:00Z Value: 4.0
# y_hourly has numeric timestamps of all 0
[(0,1.0),(0,2.0),(0,4.0)]
可以选择组合重复的时间戳记,如下所示:
y_hourly_averaged = y_hourly.transform(transformers.combine_duplicate_granularity(lambda x: sum(x)/len(x))
print(y_hourly_averaged.materialize(0,0))
这将返回:
# values corresponding to the duplicate numeric timestamp 0 have been combined using average
# average = (1+2+4)/3 = 2.33
[(0,2.33)]
了解更多信息
要使用 tspy
Python SDK ,请参阅 tspy
Python SDK 文档。
父主题: 时间序列分析