Pandasで時系列データを曜日・月・年ごとに集計する方法 📈
時系列データの分析において、特定の期間(曜日、月、四半期、年など)ごとにデータを集計することは非常に一般的かつ重要です。Pandasを使えば、日付情報からこれらの情報を抽出し、簡単に合計や平均などの統計量を算出できます。本記事では、PandasのDataFrameやSeriesを使って、時系列データを様々な期間で集計する具体的な方法を、サンプルコードを交えながら丁寧に解説します。
1. 時系列データと集計の重要性 🤔
時系列データは、時間の経過とともに変化するデータであり、その背後には様々なパターンが隠されています。例えば、小売業の売上データであれば「週末は売上が伸びる」「年末商戦で売上が急増する」といった傾向が見られることがあります。これらの傾向を把握するためには、日々のデータをそのまま見るだけでなく、週次、月次、四半期、年次といった異なる粒度で集計し、比較分析することが不可欠です。
なぜ集計が必要なのか?
-
トレンドの把握: 長期的な傾向や周期性を特定するため。
-
パターンの発見: 特定の曜日や月に繰り返されるパターンを見つけるため。
-
比較分析: 異なる期間のパフォーマンスを比較するため。
-
異常値の検出: 通常のパターンから外れた異常な値を特定するため。
2. Pandasでの時系列データ集計の基本 📊
Pandasで時系列データを集計する際には、主に以下の2つのアプローチがあります。
-
日付/時刻インデックスのプロパティを利用する:
dtアクセサを通じて、インデックスから曜日、月、年などの情報を直接抽出してグループ化する。 -
resample()メソッドを利用する: 特定の期間(週、月など)でデータをリサンプリングし、集計する。
ここでは、両方のアプローチについて詳しく見ていきましょう。
サンプルデータの準備
まずは、集計の対象となるサンプル時系列データ(DataFrame)を作成します。
import pandas as pd
import numpy as np
# 日付範囲を生成
dates = pd.date_range(start='2024-01-01', periods=60, freq='D')
# 適当な売上データを生成
np.random.seed(42) # 再現性のためにシードを設定
sales_data = np.random.randint(100, 500, size=60)
# DataFrameを作成(インデックスを日付にする)
df = pd.DataFrame({'Sales': sales_data}, index=dates)
df.index.name = 'Date' # インデックスに名前を付けておくことを推奨
print("元のデータフレーム (先頭5行):")
print(df.head())
実行結果:
元のデータフレーム (先頭5行):
Sales
Date
2024-01-01 409
2024-01-02 427
2024-01-03 143
2024-01-04 115
2024-01-05 164
3. 曜日ごとの集計 📅
週の各曜日(月曜、火曜など)ごとにデータを集計する方法です。dt.dayofweek(月曜が0、日曜が6)やdt.day_name()(曜日の名前)を利用します。
曜日ごとの合計売上
dt.day_name()で曜日名を取得し、groupby()で集計します。
# 曜日ごとの合計売上を算出
# dt.day_name()で曜日名(例: Monday, Tuesday)を取得
weekly_sum = df.groupby(df.index.dt.day_name())['Sales'].sum()
# 曜日の順序を整える(オプション)
# PandasのCategorical型を利用
days_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
weekly_sum = weekly_sum.reindex(days_order)
print("曜日ごとの合計売上:")
print(weekly_sum)
実行結果例:
曜日ごとの合計売上:
Date
Monday 2473
Tuesday 2075
Wednesday 2206
Thursday 2370
Friday 2186
Saturday 2022
Sunday 2004
Name: Sales, dtype: int64
曜日名を日本語に変換したい場合は、dt.day_name(locale='ja_JP.UTF-8')のようにロケールを指定するか、辞書でマッピングすることも可能です。
曜日ごとの平均売上
同様に、mean()を使えば平均を算出できます。
# 曜日ごとの平均売上を算出
weekly_mean = df.groupby(df.index.dt.day_name())['Sales'].mean()
weekly_mean = weekly_mean.reindex(days_order) # 順序を整える
print("\n曜日ごとの平均売上:")
print(weekly_mean)
実行結果例:
曜日ごとの平均売上:
Date
Monday 274.777778
Tuesday 230.555556
Wednesday 245.111111
Thursday 263.333333
Friday 242.888889
Saturday 224.666667
Sunday 222.666667
Name: Sales, dtype: float64
4. 月ごとの集計 🗓️
月ごとの集計も、曜日と同様にdt.month_name()またはdt.monthプロパティを利用します。
H3: 月ごとの合計売上
# 月ごとの合計売上を算出
# dt.month_name()で月名(例: January, February)を取得
monthly_sum = df.groupby(df.index.dt.month_name())['Sales'].sum()
print("\n月ごとの合計売上:")
print(monthly_sum)
実行結果例:
月ごとの合計売上:
Date
February 5937
January 9399
Name: Sales, dtype: int64
月ごとの平均売上
# 月ごとの平均売上を算出
monthly_mean = df.groupby(df.index.dt.month_name())['Sales'].mean()
print("\n月ごとの平均売上:")
print(monthly_mean)
実行結果例:
月ごとの平均売上:
Date
February 312.473684
January 253.972973
Name: Sales, dtype: float64
5. 四半期ごとの集計 季度
四半期ごとの集計にはdt.quarterプロパティが便利です。
四半期ごとの合計売上
# 四半期ごとの合計売上を算出
quarterly_sum = df.groupby(df.index.dt.quarter)['Sales'].sum()
print("\n四半期ごとの合計売上:")
print(quarterly_sum)
実行結果例:
四半期ごとの合計売上:
Date
1 15336
Name: Sales, dtype: int64
このサンプルデータでは2ヶ月分(60日)しかないため、第1四半期(1月〜3月)にすべてのデータが含まれます。より長期のデータがあれば、複数の四半期が表示されます。
6. 年ごとの集計 📆
年ごとの集計はdt.yearプロパティを使用します。
年ごとの合計売上
# 年ごとの合計売上を算出
yearly_sum = df.groupby(df.index.dt.year)['Sales'].sum()
print("\n年ごとの合計売上:")
print(yearly_sum)
実行結果例:
年ごとの合計売上:
Date
2024 15336
Name: Sales, dtype: int64
これも同様に、サンプルデータが1年分なので2024年の合計のみが表示されます。
7. resample()を使った集計 🔄
resample()メソッドは、時間的な間隔に基づいてデータをグループ化し、集計する際に非常に強力です。特に、月次や週次など、固定された期間での集計に適しています。
週次での合計売上(resample()の例)
# 週次で合計を計算 (ダウンサンプリング)
# 'W'は週の終わり(日曜)を基準
weekly_resampled_sum = df['Sales'].resample('W').sum()
print("\nresample()による週次合計売上:")
print(weekly_resampled_sum)
実行結果例:
resample()による週次合計売上:
Date
2024-01-07 2018
2024-01-14 2054
2024-01-21 2313
2024-01-28 2226
2024-02-04 2504
2024-02-11 1768
2024-02-18 2453
Freq: W-SUN, Name: Sales, dtype: int64
-
'W':週次で集計します。デフォルトでは日曜日を週の終わりとします。 -
'M':月末で集計します。 -
'Q':四半期末で集計します。 -
'Y':年末で集計します。
resample()の後にsum()やmean()、first()、last()などの集計関数を続けます。
8. まとめ ✨
Pandasを使用することで、時系列データを様々な期間(曜日、月、四半期、年)で簡単に集計し、分析することができます。
-
dtアクセサ: 日付/時刻インデックスから直接、年 (.year)、月 (.monthまたは.month_name())、曜日 (.dayofweekまたは.day_name())、四半期 (.quarter) などの情報を抽出し、groupby()と組み合わせて集計する。 -
resample()メソッド: 特定の時間間隔(週次、月次など)でデータをリサンプリングし、集計する。より柔軟な時間軸での集計が可能。
これらの強力な機能を活用することで、時系列データに隠されたパターンやトレンドを発見し、ビジネスや研究における意思決定に役立てることができます。ぜひ、ご自身の時系列データでこれらの集計方法を試してみてください!
