今回は、pandasのシリーズにインデックス付けされた時系列データの参照方法について紹介する。

例として、前回の記事で紹介した以下のサンプルシリーズを使う。

from datetime import datetime
import pandas as pd
import numpy as np
 
dates = [
    datetime(2019, 10, 1),
    datetime(2019, 10, 2),
    datetime(2019, 10, 3),
    datetime(2019, 10, 4),
    datetime(2019, 10, 5),
    datetime(2019, 10, 6)
]
 
ts = pd.Series(np.random.randn(6), index=dates)
ts
# 2019-10-01    0.476832
# 2019-10-02   -0.185948
# 2019-10-03    1.267985
# 2019-10-04    0.748634
# 2019-10-05   -1.124271
# 2019-10-06   -1.769275
# dtype: float64

基本のインデックス参照

まずは基本となるインデックス参照の例について見ていこう。

シリーズ同様、各括弧内にインデックスのラベル(この場合タイムスタンプ型)を指定することで、該当する行の値を得られる。

stamp = ts.index[2]
ts[stamp]
# 1.2679854807520052

また、日付として解釈できる文字列を直接指定して参照することも可能だ。

ts['10/6/2019']
# -1.769274721764269

ts['20191004']
# 0.7486340843842151

長い時系列データを参照する

以下のように長い時系列データを扱う例を見ていこう。

long_ts = pd.Series(np.random.randn(1000),
                   index=pd.date_range('1/1/2000', periods=1000))

long_ts
# 2000-01-01   -0.180766
# 2000-01-02    0.504275
# 2000-01-03   -0.822478
#                 ...   
# 2002-09-24   -2.188690
# 2002-09-25   -0.693634
# 2002-09-26   -1.889664
# Freq: D, Length: 1000, dtype: float64

1000日の範囲の時系列データを用意した。

こういった長い時系列データの場合、年や年月を指定して簡単に一部のデータを抽出することができる。

long_ts['2001']

# 2001-01-01    0.522564
# 2001-01-02   -0.026856
# 2001-01-03   -1.149098
#                 ...   
# 2001-12-29   -0.101378
# 2001-12-30   -1.077600
# 2001-12-31   -0.770335
# Freq: D, Length: 365, dtype: float64

long_ts['2001-04']
# 2001-04-01   -0.414521
# 2001-04-02   -1.144980
# 2001-04-03    1.385957
#                 ...   
# 2001-04-28    0.303824
# 2001-04-29   -2.781978
# 2001-04-30    0.759591
# Freq: D, dtype: float64

また、datetimeオブジェクトを使った範囲指定もできる。

以下の例は、datetimeとスライスを組み合わせて、2002/9/20以降のデータを抽出したものだ。

long_ts[datetime(2002, 9, 20):]
# 2002-09-20   -0.075612
# 2002-09-21   -0.687982
# 2002-09-22    0.841898
# 2002-09-23    1.979961
# 2002-09-24    0.310242
# 2002-09-25   -0.751955
# 2002-09-26    1.793017
# Freq: D, dtype: float64

データフレームで時系列を扱う

データフレームの場合もシリーズ同様、行のインデックス参照でデータ抽出をおこなうことができる。

以下に一例を示しておこう。

# freq引数で頻度を設定できる。「W」は曜日を表し「WED」は水曜日を、つまり水曜日のみを設定している
dates = pd.date_range('1/1/2010', periods=100, freq='W-WED')

long_df = pd.DataFrame(np.random.randn(100, 4),
                      index=dates,
                      columns=['Tokyo', 'Osaka', 'Nagoya', 'Fukuoka'])

データフレームの場合はlocでインデックス参照をおこなう。

long_df.loc[datetime(2010, 1, 20)]
# Tokyo     -0.630103
# Osaka     -2.036962
# Nagoya    -0.682478
# Fukuoka   -0.325658
# Name: 2010-01-20 00:00:00, dtype: float64

long_df.loc['2011/11/30']
# Tokyo      1.084176
# Osaka     -0.123405
# Nagoya    -0.205319
# Fukuoka   -0.255731
# Name: 2011-11-30 00:00:00, dtype: float64