Open In Colab

時系列データの処理#

本節ではpandasを利用して時系列データを処理する方法を学びます。

サンプルデータとして、厚生労働省の 新型コロナウイルス感染症 オープンデータ データを利用します。

read_csv メソッドの引数 parse_dates に渡した列名は datetime64[ns] 型として処理されます。

import pandas as pd
import plotly.express as px

df = pd.read_csv(
    "https://covid19.mhlw.go.jp/public/opendata/newly_confirmed_cases_daily.csv",
    parse_dates=["Date"],
)
df.head()
Date ALL Hokkaido Aomori Iwate Miyagi Akita Yamagata Fukushima Ibaraki ... Ehime Kochi Fukuoka Saga Nagasaki Kumamoto Oita Miyazaki Kagoshima Okinawa
0 2020-01-16 1 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
1 2020-01-17 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2 2020-01-18 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
3 2020-01-19 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
4 2020-01-20 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0

5 rows × 49 columns

df.dtypes[:5]
Date        datetime64[ns]
ALL                  int64
Hokkaido             int64
Aomori               int64
Iwate                int64
dtype: object
date = df.loc[:, "Date"]
type(date.dt)
pandas.core.indexes.accessors.DatetimeProperties

.dtアクセサ#

Series には「.dtアクセサ」と呼ばれる datetime 型の要素を操作できる機能があります。

https://pandas.pydata.org/pandas-docs/stable/reference/series.html#datetimelike-properties

date = df.loc[:, "Date"]
type(date.dt)
pandas.core.indexes.accessors.DatetimeProperties

month 属性では「月」を取得できます。

date.dt.month
0        1
1        1
2        1
3        1
4        1
        ..
1034    11
1035    11
1036    11
1037    11
1038    11
Name: Date, Length: 1039, dtype: int64

練習問題1#

date オブジェクトから曜日名を取得してください。

# 解答セル

DatetimeIndex#

DatetimeIndex は時系列データに特化したインデックスです。さまざまな方法で要素にアクセスできます。

df.set_index("Date", inplace=True)
df.head()
ALL Hokkaido Aomori Iwate Miyagi Akita Yamagata Fukushima Ibaraki Tochigi ... Ehime Kochi Fukuoka Saga Nagasaki Kumamoto Oita Miyazaki Kagoshima Okinawa
Date
2020-01-16 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-01-17 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-01-18 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-01-19 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-01-20 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0

5 rows × 48 columns

df.index
DatetimeIndex(['2020-01-16', '2020-01-17', '2020-01-18', '2020-01-19',
               '2020-01-20', '2020-01-21', '2020-01-22', '2020-01-23',
               '2020-01-24', '2020-01-25',
               ...
               '2022-11-10', '2022-11-11', '2022-11-12', '2022-11-13',
               '2022-11-14', '2022-11-15', '2022-11-16', '2022-11-17',
               '2022-11-18', '2022-11-19'],
              dtype='datetime64[ns]', name='Date', length=1039, freq=None)

locdatetime 型や文字列を指定できます。次のように文字列で指定できます。

df.loc["2020-02"]
ALL Hokkaido Aomori Iwate Miyagi Akita Yamagata Fukushima Ibaraki Tochigi ... Ehime Kochi Fukuoka Saga Nagasaki Kumamoto Oita Miyazaki Kagoshima Okinawa
Date
2020-02-01 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-02 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-03 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-04 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-05 2 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-06 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-07 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-08 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-09 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-10 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-11 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-12 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-13 3 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-14 5 1 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 1
2020-02-15 4 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-16 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-17 6 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-18 8 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-19 9 2 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 1
2020-02-20 8 1 0 0 0 0 0 0 0 0 ... 0 0 2 0 0 0 0 0 0 1
2020-02-21 13 3 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-22 23 9 0 0 0 0 0 0 0 1 ... 0 0 0 0 0 3 0 0 0 0
2020-02-23 10 7 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-24 16 6 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-25 8 1 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 2 0 0 0 0
2020-02-26 22 8 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-27 24 15 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-28 19 12 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
2020-02-29 9 4 0 0 1 0 0 0 0 0 ... 0 1 0 0 0 0 0 0 0 0

29 rows × 48 columns

df.loc["2020-12":"2021-01"]
ALL Hokkaido Aomori Iwate Miyagi Akita Yamagata Fukushima Ibaraki Tochigi ... Ehime Kochi Fukuoka Saga Nagasaki Kumamoto Oita Miyazaki Kagoshima Okinawa
Date
2020-12-01 2014 206 4 10 11 0 3 0 50 26 ... 5 5 33 10 2 18 14 10 3 27
2020-12-02 2419 176 8 4 9 0 4 5 44 24 ... 7 8 42 6 0 11 15 8 5 46
2020-12-03 2505 206 8 4 21 0 7 3 37 14 ... 5 15 31 4 0 8 18 7 11 49
2020-12-04 2435 212 6 1 21 0 3 6 85 17 ... 7 16 45 4 0 15 18 9 5 47
2020-12-05 2496 183 3 7 21 0 6 13 31 13 ... 2 19 42 3 0 8 18 8 6 41
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2021-01-27 3968 147 4 6 27 2 10 25 84 38 ... 15 1 185 7 11 22 14 17 10 131
2021-01-28 4122 115 4 0 27 2 7 15 60 34 ... 1 6 185 7 28 15 22 17 13 96
2021-01-29 3547 111 3 0 13 5 15 14 86 44 ... 8 6 159 2 18 19 20 14 19 63
2021-01-30 3330 106 9 1 23 0 6 11 69 24 ... 16 5 154 6 30 13 10 5 11 76
2021-01-31 2673 104 6 0 17 1 2 9 63 16 ... 0 1 127 5 4 8 13 11 13 39

62 rows × 48 columns

練習問題2#

df オブジェクトから2021年以降のデータを抽出してください。

# 解答セル

区間・期間の集計#

「ALL」列をSeriesとして取得します。

all_prefs = df.loc[:, "ALL"]
all_prefs.head()
Date
2020-01-16    1
2020-01-17    0
2020-01-18    0
2020-01-19    0
2020-01-20    0
Name: ALL, dtype: int64

resample メソッドを実行することで、データをリサンプリングできます。次のコードでは7日ごとの移動平均を算出しています。

resample メソッドの引数には頻度(年、月など)を示す文字列を渡します。指定できる文字列はpandasの User Guide を参照してください。

all_prefs.resample("7D").mean()
Date
2020-01-16        0.142857
2020-01-23        1.000000
2020-01-30        1.000000
2020-02-06        0.285714
2020-02-13        5.142857
                  ...     
2022-10-20    35406.428571
2022-10-27    46532.000000
2022-11-03    63376.142857
2022-11-10    78420.857143
2022-11-17    89089.000000
Freq: 7D, Name: ALL, Length: 149, dtype: float64

resample メソッドの引数を"1W" (1週間)で渡した場合は日曜日を基準に算出します。

all_prefs.resample("1W").mean()
Date
2020-01-19        0.250000
2020-01-26        0.428571
2020-02-02        1.142857
2020-02-09        0.428571
2020-02-16        2.142857
                  ...     
2022-10-23    33450.428571
2022-10-30    40330.285714
2022-11-06    57328.571429
2022-11-13    71728.000000
2022-11-20    85812.833333
Freq: W-SUN, Name: ALL, Length: 149, dtype: float64
all_prefs.resample("1W").first()
Date
2020-01-19        1
2020-01-26        0
2020-02-02        0
2020-02-09        0
2020-02-16        0
              ...  
2022-10-23    15395
2022-10-30    16851
2022-11-06    22415
2022-11-13    31703
2022-11-20    37595
Freq: W-SUN, Name: ALL, Length: 149, dtype: int64

データを可視化することで、時系列の推移を視覚的に把握できるようになります。移動平均を算出することで、時系列データのトレンドが把握しやすくなったことがわかります。可視化方法については次章で解説します。

px.line(all_prefs, title="新規陽性者数の推移")