Pandasで時系列データを曜日・月・年ごとに集計する方法 📈


 

時系列データの分析において、特定の期間(曜日、月、四半期、年など)ごとにデータを集計することは非常に一般的かつ重要です。Pandasを使えば、日付情報からこれらの情報を抽出し、簡単に合計や平均などの統計量を算出できます。本記事では、PandasのDataFrameSeriesを使って、時系列データを様々な期間で集計する具体的な方法を、サンプルコードを交えながら丁寧に解説します。


 

1. 時系列データと集計の重要性 🤔

 

時系列データは、時間の経過とともに変化するデータであり、その背後には様々なパターンが隠されています。例えば、小売業の売上データであれば「週末は売上が伸びる」「年末商戦で売上が急増する」といった傾向が見られることがあります。これらの傾向を把握するためには、日々のデータをそのまま見るだけでなく、週次、月次、四半期、年次といった異なる粒度で集計し、比較分析することが不可欠です。

 

なぜ集計が必要なのか?

 

  • トレンドの把握: 長期的な傾向や周期性を特定するため。

  • パターンの発見: 特定の曜日や月に繰り返されるパターンを見つけるため。

  • 比較分析: 異なる期間のパフォーマンスを比較するため。

  • 異常値の検出: 通常のパターンから外れた異常な値を特定するため。


 

2. Pandasでの時系列データ集計の基本 📊

 

Pandasで時系列データを集計する際には、主に以下の2つのアプローチがあります。

  1. 日付/時刻インデックスのプロパティを利用する: dtアクセサを通じて、インデックスから曜日、月、年などの情報を直接抽出してグループ化する。

  2. resample()メソッドを利用する: 特定の期間(週、月など)でデータをリサンプリングし、集計する。

ここでは、両方のアプローチについて詳しく見ていきましょう。

 

サンプルデータの準備

 

まずは、集計の対象となるサンプル時系列データ(DataFrame)を作成します。

Python
 
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()で集計します。

Python
 
# 曜日ごとの合計売上を算出
# 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()を使えば平均を算出できます。

Python
 
# 曜日ごとの平均売上を算出
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: 月ごとの合計売上

 

Python
 
# 月ごとの合計売上を算出
# 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

 

月ごとの平均売上

 

Python
 
# 月ごとの平均売上を算出
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プロパティが便利です。

 

四半期ごとの合計売上

 

Python
 
# 四半期ごとの合計売上を算出
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プロパティを使用します。

 

年ごとの合計売上

 

Python
 
# 年ごとの合計売上を算出
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()の例)

 

Python
 
# 週次で合計を計算 (ダウンサンプリング)
# '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()メソッド: 特定の時間間隔(週次、月次など)でデータをリサンプリングし、集計する。より柔軟な時間軸での集計が可能。

これらの強力な機能を活用することで、時系列データに隠されたパターンやトレンドを発見し、ビジネスや研究における意思決定に役立てることができます。ぜひ、ご自身の時系列データでこれらの集計方法を試してみてください!