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日遅らしたり進めたりできます。 オブジェクトの一覧は以下のページから確認できます。

DataOffset Objects

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には時系列データを扱う関数も充実しており使い勝手も良いので実際に手を動かして使ってみて使い方をマスターしましょう。

参考