Python上で時系列データを扱う際はdatetime
モジュールを使うのが基本です。
例えばですが、現在時刻を取得したい時は以下のように書きます。
In [1]: import datetime
In [2]: time = datetime.datetime.now()
In [3]: time
Out[3]: datetime.datetime(2018, 9, 21, 10, 29, 17, 681135)
これをPandas上でも扱えるようにしたのがTimestamp
クラスです。Timestamp
はPandasのデータ構造上での時刻の要素オブジェクトになります。時系列データを扱う方はTimestamp
の扱いに慣れておきましょう。
本記事ではpandas.Timestamp
クラスのパラメータについて解説した後、簡単な使い方について触れていきます。
Timestampクラス
冒頭でも説明した通り、PandasのTimestamp
クラスはPythonのdatetime.datetime
オブジェクトをPandasに移植したものとなるので、オブジェクトそのものの扱いについてはdatetime.datetime
のものとほぼ同一になります。
PandasではTimestampを時刻の要素としてSeriesやIndex、DataFrameを構成します。
従って、1つ1つの要素が属するクラスであるTimestamp
クラスについての理解が深まればこのような時系列データが格納されているIndexオブジェクト(DatetimeIndexオブジェクトと呼びます)やSeries,DataFrameオブジェクトの扱いもかなりわかりやすくなるはずですのでこの記事を読むことで理解していきましょう。
TimestampクラスのAPIドキュメント
まずはTimestamp
クラスのAPIドキュメントは以下の通りです。
class pandas.Timestamp
params:
パラメータ名 | 型 | 概要 |
---|---|---|
ts_input | datetimeライクなオブジェクト str,int,float |
Timestampに変換したい値。 |
freq | str,DateOffsetオブジェクト | Timestampオブジェクトが持つオフセットを指定します。 |
tz | str,pytz.timezoneオブジェクト dateutil.tz.tzfile またはNone |
タイムゾーンを指定します。 |
unit | ‘D’,’h’,’m’,’s’, ‘ms’,’us’, ‘ns’のいずれか |
UNIX時間を変換したい時にどの単位で変換をするかを指定します。’D’は日、’h’は時間(hour)、’m’は分(minute)となっています。デフォルトではナノ秒に設定されてます。 |
year,month,day | int | 年、月、日をこれらを使って個別に指定することが可能です。 |
hour,minute,second, microsecond |
int | 時、分、秒、ミリ秒を個別に指定します。 |
nanosecond | int | ナノ秒を指定します。 |
tzinfo | datetime.tzinfo | タイムゾーンの情報を入れます。 |
パラメータだけ見てもよくわからない部分が多いので、次の生成方法のまとめの部分でよく使うパラメータについて扱います。
Timestampクラスオブジェクトの生成
直接生成
まずは一番基本的な方法で生成してみます。
In [1]: import pandas as pd
In [2]: t_1 = pd.Timestamp(2018,12,18) # 2018年12月18日
In [3]: t_1
Out[3]: Timestamp('2018-12-18 00:00:00')
In [4]: t_2 = pd.Timestamp(year=2018,month=12,day=18,hour=23,minute=12,second=32
...: ) # 個別に指定することもできる
In [5]: t_2
Out[5]: Timestamp('2018-12-18 23:12:32')
UNIX時間から生成してみます。
In [9]: t_3 = pd.Timestamp(1537499090,unit='s')
In [10]: t_3
Out[10]: Timestamp('2018-09-21 03:04:50')
タイムゾーンを指定します。
In [11]: t_4 = pd.Timestamp(1537499090,unit='s', tz='Asia/Tokyo')
In [12]: t_4
Out[12]: Timestamp('2018-09-21 12:04:50+0900', tz='Asia/Tokyo')
to_datetime関数を使った生成
これが一番よく使う手法だと思いますが、変換したい文字列(数値データ)の入ったリストやSeriesなどをまとめて変換してくれる優れものです。しかも文字列のフォーマットもかなり柔軟に対応してくれます。
とはいえ、日本語を使った表記が入っている場合は対応できないのでその場合はフォーマットを指定しましょう。
詳しい使い方は以下の記事で解説してます。
Pandasで時間や日付データに変換するto_datetime関数の使い方 /features/pandas-to-datetime.html
In [16]: pd.to_datetime('2018-9-21')
Out[16]: Timestamp('2018-09-21 00:00:00')
In [18]: pd.to_datetime('2018/09/21 12:21+0900') #このようにタイムゾーン指定もできる。
Out[18]: Timestamp('2018-09-21 03:21:00')
In [19]: pd.to_datetime('09/21/2018 03:34')
Out[19]: Timestamp('2018-09-21 03:34:00')
In [21]: pd.to_datetime('2018年9月21日 15時34分',format='%Y年%m月%d日 %H時%M分')
Out[21]: Timestamp('2018-09-21 15:34:00')
date_range関数を使った連続した時刻データの生成
インデックスの生成などでよく使われるdate_range
関数です。
最初に起点となる日時を指定し、freq
で生成する値の頻度、periods
で生成する値の個数を指定します。
この場合、生成されるのはDateTimeIndexオブジェクトですが1つ1つの要素はTimestampオブジェクトです。
In [22]: pd.date_range('2018-9-21', periods=3, freq='D') # 1日ごとに3つ
Out[22]: DatetimeIndex(['2018-09-21', '2018-09-22', '2018-09-23'], dtype='datetime64[ns]', freq='D')
In [23]: time_idx = pd.date_range('2018/9/21',periods=3,freq='W') # 1週間ごとに生成
In [24]: time_idx # 毎週日曜がカウントされるので金曜の2018年9月21日は入らない。
Out[24]: DatetimeIndex(['2018-09-23', '2018-09-30', '2018-10-07'], dtype='datetime64[ns]', freq='W-SUN')
In [25]: type(time_idx[0])
Out[25]: pandas._libs.tslibs.timestamps.Timestamp
Timestampオブジェクトから情報取得
次に、生成したTimestampオブジェクトからいろいろ情報を取得してみます。
In [33]: t_5 = pd.Timestamp(2018,12,18,12,34,35,300000,123321) # 2018年12月18日1
...: 2時34分35秒300ミリ秒123321ナノ秒
In [34]: t_5
Out[34]: Timestamp('2018-12-18 12:34:35.300123321')
様々な属性(attribute)を呼び出してみます。
In [55]: t_5.year
Out[55]: 2018
In [35]: t_5.day # 日付
Out[35]: 18
In [50]: t_5.month
Out[50]: 12
In [42]: t_5.hour
Out[42]: 12
In [51]: t_5.minute
Out[51]: 34
In [52]: t_5.nanosecond
Out[52]: 123321
In [36]: t_5.dayofweek # 曜日(0が日曜)
Out[36]: 1
In [37]: t_5.dayofyear # 年始からの経過日数
Out[37]: 352
In [56]: t_5.week
Out[56]: 51
In [57]: t_5.weekofyear # 年の中で第何週目か
Out[57]: 51
In [38]: t_5.days_in_month # その月の最大日数(12月は31日まであるので31まで)
Out[38]: 31
In [43]: t_5.is_leap_year
Out[43]: False
In [44]: t_5.is_month_end # 月終わりかどうか
Out[44]: False
In [45]: t_5.is_month_start # 月始めかどうか
Out[45]: False
In [46]: t_5.is_quarter_end # 四半期終わりかどうか
Out[46]: False
In [47]: t_5.is_quarter_start # 四半期始めかどうか
Out[47]: False
In [48]: t_5.is_year_end # 年末かどうか
Out[48]: False
In [49]: t_5.is_year_start # 年始かどうか
Out[49]: False
In [53]: t_5.quarter
Out[53]: 4
In [58]: t_5.value # エポックナノ秒
Out[58]: 1545136475300123321
タイムゾーンの指定
今度はタイムゾーンの指定です。
まず、tz_localize
関数を使って表示している時刻がどこのタイムゾーンのものなのかを指定し、次にtz_convert
を使ってそこから指定したタイムゾーンの時刻を表示します。
In [59]: t_tz = pd.Timestamp('2018-12-13 12:00')
In [60]: t_tz.tzinfo # タイムゾーンを指定していないので何も返らない
In [61]: t_tz = t_tz.tz_localize('utc') # 協定世界時(UTC)にタイムゾーンを設定
In [62]: t_tz.tzinfo
Out[62]: <UTC>
これでタイムゾーンの指定が完了しました。これにより、UTCでの12時ちょうどを設定したことになります。
では、この時の日本の時間はいつなのかを知りたい時、tz_convert
関数が使えます。
日本はタイムゾーン指定で'Asia/Tokyo'
と指定します。この表記の一覧は以下のコマンドで取得できます。
約600個ほどのタイムゾーンがリストに入っています。
Pandasもこれに基づいてタイムゾーンを指定しています。
In [64]: import pytz
In [65]: pytz.all_timezones
Out[65]:
['Africa/Abidjan',
'Africa/Accra',
'Africa/Addis_Ababa',
'Africa/Algiers',
'Africa/Asmara',
'Africa/Asmera',
.
.
.
'Universal',
'W-SU',
'WET',
'Zulu']
では、実際にタイムゾーンを指定します。
In [67]: t_tz
Out[67]: Timestamp('2018-12-13 12:00:00+0000', tz='UTC')
In [68]: t_tz = t_tz.tz_convert('Asia/Tokyo')
In [69]: t_tz
Out[69]: Timestamp('2018-12-13 21:00:00+0900', tz='Asia/Tokyo')
In [70]: t_tz = t_tz.tz_convert('America/Chicago')
In [71]: t_tz
Out[71]: Timestamp('2018-12-13 06:00:00-0600', tz='America/Chicago')
tz_localize(None)
またはtz_convert(None)
でタイムゾーンを削除できます。
この時、時刻はUTCのものに戻されます。
In [73]: t_tz.tz_convert(None) # UTCのものに戻してタイムゾーンを削除
Out[73]: Timestamp('2018-12-13 12:00:00')
In [74]: t_tz.tz_localize(None) # 現在表示している時刻をそのまま残してタイムゾーンを削除
Out[74]: Timestamp('2018-12-13 06:00:00')
offsetsオブジェクトを使った加減
offsetsオブジェクトを使った日付を1日遅らしたり進めたりできます。 オブジェクトの一覧は以下のページから確認できます。
In [75]: import pandas.tseries.offsets as offsets
In [76]: t_tz
Out[76]: Timestamp('2018-12-13 06:00:00-0600', tz='America/Chicago')
In [77]: t = pd.Timestamp(2018,12,10)
In [78]: t
Out[78]: Timestamp('2018-12-10 00:00:00')
In [79]: t + offsets.Day(3) # 3日後
Out[79]: Timestamp('2018-12-13 00:00:00')
In [80]: t - offsets.Day(3) # 3日前
Out[80]: Timestamp('2018-12-07 00:00:00')
In [81]: t + offsets.Hour(3) # 3時間ご
Out[81]: Timestamp('2018-12-10 03:00:00')
In [82]: t + offsets.YearEnd() # 年末
Out[82]: Timestamp('2018-12-31 00:00:00')
日付データの差をとる
Timestamp
オブジェクト同士で差をとると、Timedeltaオブジェクトが生成されます。
In [85]: delta = t - pd.Timestamp(2018, 12, 8, 22, 32)
In [86]: delta
Out[86]: Timedelta('1 days 01:28:00')
In [87]: t_tz + delta # timedeltaで足し合わせることもできる
Out[87]: Timestamp('2018-12-14 07:28:00-0600', tz='America/Chicago')
In [88]: t_tz
Out[88]: Timestamp('2018-12-13 06:00:00-0600', tz='America/Chicago')
まとめ
今回はTimestamp
オブジェクトの扱い方について一通りまとめてみました。基本的にはPythonにあるdatetime.datetime
型と同一で、Pandas用に若干拡張されているようです。
Pandasには時系列データを扱う関数も充実しており使い勝手も良いので実際に手を動かして使ってみて使い方をマスターしましょう。