In [1]: import pandas as pd

In [2]: import matplotlib.pyplot as plt
このチュートリアルで使用されるデータ
  • このチュートリアルでは、\(NO_2\)と2.5マイクロメートル未満の粒子状物質に関する大気質データを使用します。これはOpenAQによって提供され、py-openaqパッケージを使用してダウンロードされています。air_quality_no2_long.csv"データセットは、パリ、アントワープ、ロンドンの測定ステーション *FR04014*、*BETR801*、*London Westminster* の\(NO_2\)値を提供します。

    生のデータへ
    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だけでなく、yearquarterなどです。これらのプロパティはすべて、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アクセサーによってもアクセスできる、pandas Timestampの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)$");
    
    ../../_images/09_bar_chart.png

    前のケースと同様に、特定の統計量(例:平均\(NO_2\))を**1日の各時間ごと**に計算します。分割-適用-結合アプローチを再び使用できます。この場合、dtアクセサーによってもアクセスできる、pandas Timestampの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();
    
    ../../_images/09_time_section.png

    **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操作に似ています。

  • 目標頻度を定義する文字列(例:M5Hなど)を使用して、時間ベースのグループ化を提供します。

  • meanmaxなどの集計関数を必要とします。

ユーザーガイドへ

時系列頻度の定義に使用されるエイリアスの概要は、オフセットエイリアスの概要表に示されています。

定義されている場合、時系列の頻度は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));
    
    ../../_images/09_resample_mean.png
ユーザーガイドへ

時系列のresamplingの機能に関する詳細は、リサンプリングに関するユーザーガイドセクションで提供されています。

覚えておくこと

  • 有効な日付文字列は、to_datetime関数を使用するか、読み取り関数の一部としてdatetimeオブジェクトに変換できます。

  • pandasのDatetimeオブジェクトは、dtアクセサーを使用して、計算、論理演算、および便利な日付関連プロパティをサポートしています。

  • DatetimeIndexには、これらの日付関連のプロパティが含まれており、便利なスライスをサポートしています。

  • Resampleは、時系列の頻度を変更するための強力なメソッドです。

ユーザーガイドへ

時系列の完全な概要は、時系列と日付の機能のページに記載されています。