IBM Cloud Docs
使用時間參照系統

使用時間參照系統

時間參照系統 (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:0109:00:02 (讀取為 hh:mm:ss) 正向及反向對映至一分鐘的時間記號會分別產生時間戳記 09:00:0009: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, time_tick=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 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, time_tick=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(EDT 時區)-4 個小時,並擷取時間計數一小時。 另請注意,設定 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 會變更數值時間戳記。

下列程式碼範例顯示在未使用 with_trs的情況下,於配置時設定 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(time_tick=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 以將 time_tick 變更為一分鐘,並保留原始時間偏移 (1970 年 1 月 1 日午夜 12 點 GMT):

y_minutely_1970 = y.with_trs(time_tick=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 以將 time_tick 變更為一分鐘,並將偏移變更為 2019 年 1 月 1 日午夜 GMT:

zdt2 = datetime.datetime(2019,1,1,0,0,0,0,tzinfo=datetime.timezone.utc)
y_minutely = y.with_trs(time_tick=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

為了更充分地瞭解它對後處理的影響,讓我們檢查下列各項。 請注意,數值時間戳記上的 get_values 會在與時間序列相關聯的基礎數值時間戳記上運作。

print(y.get_values(0,2))
print(y_minutely_1970.get_values(0,2))
print(y_minutely.get_values(0,2))

這會傳回:

# numeric timestamps in y are in the range 1546300800, 1546300920 and thus y.get_values(0,2) is empty
[]
# numeric timestamps in y_minutely_1970 are in the range 25771680, 25771682 and thus y_minutely_1970.get_values(0,2) is empty
[]
# numeric timestamps in y_minutely are in the range 0, 2
[(0,1.0),(1,2.0),(2,4.0)]

get_values 方法也可以套用至日期時間物件。 如果基礎時間序列未與 TRS 相關聯(如果 TRS 為「無」),這會導致發生異常狀況。 假設基礎時間序列具有 TRS,則會使用 TRS 將 datetime 物件對映至一個數值範圍。

# 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.get_values(dt_beg, dt_end))
print(y_minutely_1970.get_values(dt_beg, dt_end))
print(y_minutely.get_values(dt_beg, dt_end))

# get_values on y in UTC millis
[(1546300800,1.0),(1546300860,2.0), (1546300920,4.0)]
# get_values on y_minutely_1970 in UTC minutes
[(25771680,1.0),(25771681,2.0),(25771682,4.0)]
# get_values 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(time_tick=datetime.timedelta(hours=1), start_time=zdt2)
print(y_minutely)
print(y_minutely.get_values(0,2))

print(y_hourly)
print(y_hourly.get_values(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_time_ticks(lambda x: sum(x)/len(x))
print(y_hourly_averaged.get_values(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 文件