In [1]: import pandas as pd
In [2]: import matplotlib.pyplot as plt
-
大気質データ
In [3]: air_quality = pd.read_csv("data/air_quality_no2_long.csv") In [4]: air_quality = air_quality.rename(columns={"date.utc": "datetime"}) In [5]: air_quality.head() Out[5]: city country datetime location parameter value unit 0 Paris FR 2019-06-21 00:00:00+00:00 FR04014 no2 20.0 µg/m³ 1 Paris FR 2019-06-20 23:00:00+00:00 FR04014 no2 21.8 µg/m³ 2 Paris FR 2019-06-20 22:00:00+00:00 FR04014 no2 26.5 µg/m³ 3 Paris FR 2019-06-20 21:00:00+00:00 FR04014 no2 24.9 µg/m³ 4 Paris FR 2019-06-20 20:00:00+00:00 FR04014 no2 21.4 µg/m³
In [6]: air_quality.city.unique() Out[6]: array(['Paris', 'Antwerpen', 'London'], dtype=object)
時系列データを簡単に扱う方法#
pandasの日時プロパティの使用#
datetime
列の日付をプレーンテキストではなくdatetimeオブジェクトとして扱いたいIn [7]: air_quality["datetime"] = pd.to_datetime(air_quality["datetime"]) In [8]: air_quality["datetime"] Out[8]: 0 2019-06-21 00:00:00+00:00 1 2019-06-20 23:00:00+00:00 2 2019-06-20 22:00:00+00:00 3 2019-06-20 21:00:00+00:00 4 2019-06-20 20:00:00+00:00 ... 2063 2019-05-07 06:00:00+00:00 2064 2019-05-07 04:00:00+00:00 2065 2019-05-07 03:00:00+00:00 2066 2019-05-07 02:00:00+00:00 2067 2019-05-07 01:00:00+00:00 Name: datetime, Length: 2068, dtype: datetime64[ns, UTC]
最初は、
datetime
の値は文字列であり、日時操作(例:年、曜日などを抽出)を提供しません。to_datetime
関数を適用することにより、pandasは文字列を解釈し、これらをdatetime(つまり、datetime64[ns, UTC]
)オブジェクトに変換します。pandasでは、これらのdatetimeオブジェクトを標準ライブラリのdatetime.datetime
と同様にpandas.Timestamp
と呼びます。
注記
多くのデータセットは列の1つに日時情報を含んでいるため、pandas.read_csv()
やpandas.read_json()
などのpandas入力関数は、parse_dates
パラメータにTimestampとして読み取る列のリストを使用してデータを読み取るときに、日付への変換を実行できます。
pd.read_csv("../data/air_quality_no2_long.csv", parse_dates=["datetime"])
これらのpandas.Timestamp
オブジェクトはなぜ便利なのでしょうか?いくつかの例で、追加された価値を示しましょう。
私たちが扱っている時系列データセットの開始日と終了日は何ですか?
In [9]: air_quality["datetime"].min(), air_quality["datetime"].max()
Out[9]:
(Timestamp('2019-05-07 01:00:00+0000', tz='UTC'),
Timestamp('2019-06-21 00:00:00+0000', tz='UTC'))
日付にpandas.Timestamp
を使用すると、日付情報を使用して計算し、比較できるようになります。したがって、これを使用して時系列の長さを取得できます。
In [10]: air_quality["datetime"].max() - air_quality["datetime"].min()
Out[10]: Timedelta('44 days 23:00:00')
結果はpandas.Timedelta
オブジェクトです。これは、標準Pythonライブラリのdatetime.timedelta
と似ており、時間間隔を定義します。
pandasでサポートされているさまざまな時間概念については、時間関連の概念に関するユーザーガイドセクションで説明されています。
測定月のみを含む新しい列を
DataFrame
に追加したいIn [11]: air_quality["month"] = air_quality["datetime"].dt.month In [12]: air_quality.head() Out[12]: city country datetime ... value unit month 0 Paris FR 2019-06-21 00:00:00+00:00 ... 20.0 µg/m³ 6 1 Paris FR 2019-06-20 23:00:00+00:00 ... 21.8 µg/m³ 6 2 Paris FR 2019-06-20 22:00:00+00:00 ... 26.5 µg/m³ 6 3 Paris FR 2019-06-20 21:00:00+00:00 ... 24.9 µg/m³ 6 4 Paris FR 2019-06-20 20:00:00+00:00 ... 21.4 µg/m³ 6 [5 rows x 8 columns]
日付に
Timestamp
オブジェクトを使用することにより、pandasによって多くの時間関連のプロパティが提供されます。たとえば、month
だけでなく、year
、quarter
などです。これらのプロパティはすべて、dt
アクセサーによってアクセスできます。
既存の日付プロパティの概要は、時間と日付のコンポーネントの概要表に示されています。datetimeのようなプロパティを返すdt
アクセサーの詳細については、dtアクセサーの専用セクションで説明されています。
各測定場所の曜日ごとの平均\(NO_2\)濃度はどれくらいですか?
In [13]: air_quality.groupby( ....: [air_quality["datetime"].dt.weekday, "location"])["value"].mean() ....: Out[13]: datetime location 0 BETR801 27.875000 FR04014 24.856250 London Westminster 23.969697 1 BETR801 22.214286 FR04014 30.999359 ... 5 FR04014 25.266154 London Westminster 24.977612 6 BETR801 21.896552 FR04014 23.274306 London Westminster 24.859155 Name: value, Length: 21, dtype: float64
統計計算のチュートリアルで提供されている
groupby
による分割-適用-結合パターンを覚えていますか?ここでは、特定の統計量(例:平均\(NO_2\))を**曜日ごと**および**測定場所ごと**に計算します。曜日にグループ化するには、dt
アクセサーによってもアクセスできる、pandasTimestamp
のdatetimeプロパティweekday
(月曜日= 0、日曜日= 6)を使用します。場所と曜日の両方のグループ化を行うことで、これらの各組み合わせについて平均の計算を分割できます。危険
これらの例では非常に短い時系列を扱っているため、分析では長期的な代表的な結果は得られません!
すべてのステーションの時系列の1日における典型的な\(NO_2\)パターンをプロットします。言い換えれば、1日の各時間ごとの平均値はどれくらいですか?
In [14]: fig, axs = plt.subplots(figsize=(12, 4)) In [15]: air_quality.groupby(air_quality["datetime"].dt.hour)["value"].mean().plot( ....: kind='bar', rot=0, ax=axs ....: ) ....: Out[15]: <Axes: xlabel='datetime'> In [16]: plt.xlabel("Hour of the day"); # custom x label using Matplotlib In [17]: plt.ylabel("$NO_2 (µg/m^3)$");
前のケースと同様に、特定の統計量(例:平均\(NO_2\))を**1日の各時間ごと**に計算します。分割-適用-結合アプローチを再び使用できます。この場合、
dt
アクセサーによってもアクセスできる、pandasTimestamp
のdatetimeプロパティhour
を使用します。
インデックスとしてのDatetime#
リシェイプのチュートリアルでは、各測定場所を別々の列としてデータテーブルをリシェイプするためにpivot()
が導入されました。
In [18]: no_2 = air_quality.pivot(index="datetime", columns="location", values="value")
In [19]: no_2.head()
Out[19]:
location BETR801 FR04014 London Westminster
datetime
2019-05-07 01:00:00+00:00 50.5 25.0 23.0
2019-05-07 02:00:00+00:00 45.0 27.7 19.0
2019-05-07 03:00:00+00:00 NaN 50.4 19.0
2019-05-07 04:00:00+00:00 NaN 61.9 16.0
2019-05-07 05:00:00+00:00 NaN 72.4 NaN
注記
データをピボットすることにより、日時情報がテーブルのインデックスになりました。一般に、列をインデックスとして設定するには、set_index
関数を使用します。
datetimeインデックス(つまり、DatetimeIndex
)を使用すると、強力な機能が提供されます。たとえば、時系列プロパティを取得するためにdt
アクセサーは必要ありませんが、これらのプロパティはインデックスで直接使用できます。
In [20]: no_2.index.year, no_2.index.weekday
Out[20]:
(Index([2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019,
...
2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019],
dtype='int32', name='datetime', length=1033),
Index([1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
...
3, 3, 3, 3, 3, 3, 3, 3, 3, 4],
dtype='int32', name='datetime', length=1033))
その他の利点としては、期間の便利なサブセット化や、プロット上の時間スケールの調整などがあります。これをデータに適用してみましょう。
5月20日から5月21日までの各ステーションの\(NO_2\)値のプロットを作成します。
In [21]: no_2["2019-05-20":"2019-05-21"].plot();
**datetimeに解析される文字列**を提供することにより、
DatetimeIndex
でデータの特定のサブセットを選択できます。
DatetimeIndex
と文字列を使用したスライスに関する詳細情報は、時系列インデックスのセクションで提供されています。
時系列を別の頻度にリサンプリングする#
現在の時間別時系列値を、各ステーションの月間最大値に集計します。
In [22]: monthly_max = no_2.resample("ME").max() In [23]: monthly_max Out[23]: location BETR801 FR04014 London Westminster datetime 2019-05-31 00:00:00+00:00 74.5 97.0 97.0 2019-06-30 00:00:00+00:00 52.5 84.7 52.0
datetimeインデックスを持つ時系列データの非常に強力なメソッドは、時系列を別の頻度に
resample()
する機能です(例:秒単位のデータを5分単位のデータに変換する)。
resample()
メソッドはgroupby操作に似ています。
目標頻度を定義する文字列(例:
M
、5H
など)を使用して、時間ベースのグループ化を提供します。mean
、max
などの集計関数を必要とします。
時系列頻度の定義に使用されるエイリアスの概要は、オフセットエイリアスの概要表に示されています。
定義されている場合、時系列の頻度はfreq
属性によって提供されます。
In [24]: monthly_max.index.freq
Out[24]: <MonthEnd>
各ステーションの1日平均\(NO_2\)値のプロットを作成します。
In [25]: no_2.resample("D").mean().plot(style="-o", figsize=(10, 5));
時系列のresampling
の機能に関する詳細は、リサンプリングに関するユーザーガイドセクションで提供されています。
覚えておくこと
有効な日付文字列は、
to_datetime
関数を使用するか、読み取り関数の一部としてdatetimeオブジェクトに変換できます。pandasのDatetimeオブジェクトは、
dt
アクセサーを使用して、計算、論理演算、および便利な日付関連プロパティをサポートしています。DatetimeIndex
には、これらの日付関連のプロパティが含まれており、便利なスライスをサポートしています。Resample
は、時系列の頻度を変更するための強力なメソッドです。
時系列の完全な概要は、時系列と日付の機能のページに記載されています。