時間参照システム (TRS) は、時間を特定するために使用されるローカル・システム、地域システム、またはグローバル・システムです。
時間参照システムは、タイム・スタンプとその数値表現の間で順方向マッピングと逆マッピングを行うための、特定の射影を定義します。 大部分のユーザーがよく知っている一般的な例として UTC 時間があります。UTC 時間では、タイム・スタンプ (例えば、2019 年 1 月 1 日午前 0 時 (GMT)) が 64 ビット整数値 (1546300800000) にマップされ、これにより 1970 年 1 月 1 日午前 0 時 (GMT) から経過した時間値 (ミリ秒単位) が取り込まれます。 一般的に、タイム・スタンプ値は人間が読むのに適しており、数値表現はマシン処理に適しています。
時系列ライブラリーで、時系列を TRS に関連付けることができます。 TRS は以下のもので構成されます。
- 時間の細分度 (例えば、1 分) を取り込む時間目盛り
- 開始時刻をキャプチャするタイムゾーン付き日/時刻。例えば、
。 開始時刻から経過した時間目盛りの数を計算することで、タイム・スタンプが数値表現にマップされます。 数値表現は細分度によってスケーリングされ、タイム・スタンプにマップされるときに開始時刻によってシフトされます。1 Jan 2019, 12 midnight US Eastern Daylight Savings time (EDT)
このように順方向の射影を行ってから逆の射影を行うと、時間の損失が生じる可能性があることに注意してください。 例えば、時系列の真の時間細分度が秒単位の場合、タイム・スタンプ
および 09:00:01
( 09:00:02
として読み取られる) を 1 分の細分度に順方向および逆方向にマップすると、それぞれタイム・スタンプ hh:mm:ss
および 09:00:00
になります。 この例では、細分度が秒単位の時系列が分にマップされているため、逆マッピングで情報が失われています。 ただし、マップ後の細分度が入力時系列の細分度よりも高い場合は (具体的に言えば、時系列の細分度がマップ後の細分度の整数倍である場合)、順方向の射影を行ってから逆の射影を行っても、情報が失われないことが保証されます。 例えば、細分度が分単位の時系列を秒にマッピングし、それを分に逆射影すると、情報が失われることなくタイム・スタンプが再構築されます。09:00:00
TRSの設定
時系列が作成されると、その時系列は TRS に関連付けられます (TRS が指定されていない場合は、「なし」)。 TRS が「なし」の場合、数値をタイム・スタンプにマップすることはできません。 TRS は、作成時にのみ時系列に設定できることに注意してください。 時系列は設計上、変更不可能なオブジェクトであるためです。 変更不可能であることは、ライブラリーを Apache Spark などのマルチスレッド環境や分散コンピューティング環境で使用する場合に役立ちます。 TRS を設定できるのは作成時だけですが、次のセクションの説明に従って
メソッドを使用して 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の変更
関数を使用して、時系列に関連付けられたTRSを変更できます。 入力時系列が TRS に関連付けられていない場合 (TRS が「なし」の場合)、この関数は例外をスローすることに注意してください。 with_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
を1分に変更し、元の時刻オフセット(1970年1月1日午前0時GMT)を保持する方法を示しています:granularity
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
を1分に変更し、オフセットを2019年1月1日の午前0時GMTに変更します:granularity
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)]
メソッド
は、日時オブジェクトにも適用できます。 その場合、基本の時系列が TRS に関連付けられていない場合 (TRS が「なし」の場合) は、例外が発生します。 基本の時系列が TRS に関連付けられていると仮定すると、datetime オブジェクトは TRS を使用して数値範囲にマップされます。materialize
# 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 を変更した結果として、重複するタイム・スタンプが発生する可能性があります。 以下の例では、細分度を 1 時間に変更して、タイム・スタンプが重複するようにします。 時系列ライブラリーは、重複するタイム・スタンプをシームレスに処理し、重複するタイム・スタンプに関連付けられている複数の値を、例えば重複するタイム・スタンプでグループ化された値の平均値を計算することで 1 つの値に減らすための便利なコンバイナーを備えています。
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)]
もっと見る
PythonSDKを使用するには、tspy
PythonSDK資料を参照してください。tspy
親トピック: 時系列分析