Python で解析 23
“Advent Calendar 2013 - Python で解析!” の二十三日目。DataFrame - 16
今回は Period について。Timestamp が時刻、Period が時間を取り扱う。時間というより、期間の方が語感としては近いかもしれない。
1. Period
だいたいの言語で、日付型や時刻型は用意されているが、期間を表すオブジェクトというのは、珍しい気がする。日付型なり、時刻型なり…を使って、開始日、終了日を自分で管理するのに慣れてしまっているだけかもしれないが…。
まずは 2013 年。
In [1]: import pandas as pd In [2]: p1 = pd.Period('2013') In [3]: p1 Out[3]: Period('2013', 'A-DEC') In [4]: p1.start_time Out[4]: Timestamp('2013-01-01 00:00:00', tz=None) In [5]: p1.end_time Out[5]: Timestamp('2013-12-31 23:59:59.999999999', tz=None)
2013年1月。
In [6]: p2 = pd.Period('2013-01') In [7]: p2 Out[7]: Period('2013-01', 'M') In [8]: p2.start_time Out[8]: Timestamp('2013-01-01 00:00:00', tz=None) In [9]: p2.end_time Out[9]: Timestamp('2013-01-31 23:59:59.999999999', tz=None)
日単位や時単位の Period も作れるのだが、文字列をうまくパースしてくれない。リファレンスのサンプルには載っているのだが、やってみるとエラーが表示される。代替として、個別のパラメーターを指定して作成してみることにする。
In [10]: p3 = pd.Period(year=2013, month=12, day=24, freq='D') In [11]: p3 Out[11]: Period('2013-12-24', 'D') In [12]: p3.start_time Out[12]: Timestamp('2013-12-24 00:00:00', tz=None) In [13]: p3.end_time Out[13]: Timestamp('2013-12-24 23:59:59.999999999', tz=None)
時単位の場合。
In [14]: p4 = pd.Period(year=2013, month=12, day=24, hour=9, freq='H') In [15]: p4 Out[15]: Period('2013-12-24 09:00', 'H') In [16]: p4.start_time Out[16]: Timestamp('2013-12-24 09:00:00', tz=None) In [17]: p4.end_time Out[17]: Timestamp('2013-12-24 09:59:59.999999999', tz=None)
Period は、自由な期間 (任意の開始時刻、終了時刻) を表現することはできない。1 時間、1日、ひと月、1四半期などの、用意されている範囲で活用するもののようだ。
2. PeriodIndex
Period のリストを渡して作ってみる。
In [18]: pi1 = pd.PeriodIndex([pd.Period('2011'), pd.Period('2012'), pd.Period('2013')]) In [19]: pi1 Out[19]: <class 'pandas.tseries.period.PeriodIndex'> freq: A-DEC [2011, ..., 2013] length: 3 In [20]: type(pi1) Out[20]: pandas.tseries.period.PeriodIndex
開始、終了を指定して作ってみる。
In [21]: pi2 = pd.PeriodIndex(start='2013-1', end='2013-12', freq='M') In [22]: pi2 Out[22]: <class 'pandas.tseries.period.PeriodIndex'> freq: M [2013-01, ..., 2013-12] length: 12
月間や年間の集計などの用途で活用できそうだ。
3. 活用例
PeriodIndex を使った DataFrame を作ってみる。
In [23]: df = pd.DataFrame({ ....: 'uu': [1000, 2000, 3000, 4000, 5000, 60000] ....: }, index=pd.PeriodIndex(start='2012-10', end='2013-3', freq='M')) In [24]: df Out[24]: uu 2012-10 1000 2012-11 2000 2012-12 3000 2013-01 4000 2013-02 5000 2013-03 60000
2012 年分だけ抽出する。
In [25]: df['2012'] Out[25]: uu 2012-10 1000 2012-11 2000 2012-12 3000
2012年12月分だけ抽出する。
In [26]: df['2012-12'] Out[26]: uu 2012-12 3000
ロジックを書かずに、こーゆーことができるのが便利だ。
In [27]: df[df.index >= pd.datetime(2012, 12, 15)] Out[27]: uu 2012-12 3000 2013-01 4000 2013-02 5000 2013-03 60000
イコールを含まない場合はこうなる。
In [28]: df[df.index > pd.datetime(2012, 12, 15)] Out[28]: uu 2013-01 4000 2013-02 5000 2013-03 60000
直感的な振る舞いではない気もするが、妥当な振る舞いのような気もする。ま、どちらかと言えば、事例のフィルター条件があまりよろしくないので、実際に活用する場合は、分かりやすいフィルター条件を心がけたいところ。
今回はこんなところで。