Pandasで時系列データを効率的にリサンプリング!resampleとasfreqを徹底解説
Pandasは、時系列データ分析において非常に強力なライブラリです。特に、**resampleとasfreq**は、異なる時間間隔でデータを集計したり、データの頻度を変更したりする際に不可欠なメソッドです。本記事では、これら2つのメソッドについて、具体的なコード例を交えながら詳しく解説します。
時系列データのリサンプリングとは?
時系列データのリサンプリングとは、データの時間間隔(頻度)を変更することです。例えば、日次のデータを週次や月次に変換したり、逆に時間ごとのデータをより細かい間隔(例:15分ごと)に分解したりする際に利用します。
リサンプリングは大きく分けて2つの種類があります。
-
ダウンサンプリング: より粗い時間間隔にデータを集約すること(例:日次 → 月次)
-
アップサンプリング: より細かい時間間隔にデータを引き伸ばすこと(例:日次 → 時間ごと)
これらの操作は、データの傾向分析や、異なる頻度のデータセットを結合する際に非常に役立ちます。
resampleメソッドでデータを柔軟に集計
resampleメソッドは、**時系列データのダウンサンプリングによく利用され、指定した時間間隔でデータをグループ化し、様々な集計処理を行うことができます。**例えば、日次の売上データを月次で合計したり、時間ごとのセンサーデータを日次で平均したりする際に使用します。
resampleの基本的な使い方
まず、時系列データを持つPandas DataFrameを作成しましょう。
import pandas as pd
import numpy as np
# サンプルデータの作成
index = pd.date_range('2024-01-01', periods=100, freq='D')
data = np.random.rand(100) * 100
df = pd.DataFrame({'value': data}, index=index)
print("元のデータ (一部):\n", df.head())
ダウンサンプリングの例: 日次データを週次合計に
日次のデータを週次データに変換し、各週のvalueの合計を計算してみましょう。
# 週次合計にリサンプリング
weekly_sum = df.resample('W').sum()
print("\n週次合計:\n", weekly_sum.head())
-
'W': 週次を表すエイリアスです。 -
.sum(): グループ化されたデータに対して合計値を計算します。他にも、mean(),max(),min(),count()など、様々な集計関数が利用できます。
月次平均へのリサンプリング
同様に、月次データにリサンプリングして平均を計算することも簡単です。
# 月次平均にリサンプリング
monthly_mean = df.resample('M').mean()
print("\n月次平均:\n", monthly_mean.head())
-
'M': 月末を表すエイリアスです。
resampleの便利な引数
resampleには、より柔軟なリサンプリングを可能にする引数があります。
rule引数: リサンプリングの頻度
rule引数には、上記で示した'W'や'M'のようなオフセットエイリアスを指定します。よく使われるオフセットエイリアスには以下のようなものがあります。
| オフセットエイリアス | 意味 |
D |
日次 |
W |
週次 |
M |
月次(月末) |
QS |
四半期開始 |
AS |
年次(年初) |
H |
時間ごと |
T (または min) |
分ごと |
S |
秒ごと |
label引数: 集計期間のラベル位置
集計されたデータのインデックス(日付)を、その期間の開始日または終了日のどちらにするかを指定できます。
-
'left': 期間の開始日をラベルにする(デフォルト) -
'right': 期間の終了日をラベルにする
# 週次合計、ラベルを期間の終了日に設定
weekly_sum_end_label = df.resample('W', label='right').sum()
print("\n週次合計 (ラベル終了日):\n", weekly_sum_end_label.head())
origin引数: リサンプリングの基準点
リサンプリングの期間をどこから始めるかを指定します。これにより、特定の曜日から週を始めたい場合などに便利です。
# 週次合計、月曜日を週の開始に設定 (例: 'start_day_of_week')
# origin='start_day_of_week' は、指定された曜日の00:00:00を基準にする
weekly_sum_monday_origin = df.resample('W', origin='start_day_of_week').sum()
print("\n週次合計 (週の開始を月曜日に設定):\n", weekly_sum_monday_origin.head())
origin引数は、リサンプリングのバケットの開始点を制御します。例えば、デフォルトでは週の始まりは日曜日ですが、origin='start_day_of_week'とすることで、データセット内の最初の週の開始日を基準に週が区切られます。より具体的に特定の開始日を指定したい場合は、日付文字列やタイムスタンプを渡すことも可能です。
asfreqメソッドでデータの頻度を変更
asfreqメソッドは、**時系列データの頻度を単純に変更し、欠損値がある場合にはそれをNaNで埋める際に使用されます。**主にアップサンプリングの際に利用されますが、ダウンサンプリングで特定の頻度に合わせてデータを抽出する際にも使えます。
asfreqの基本的な使い方
asfreqは、resampleのように集計処理を行わず、指定した頻度でインデックスを再構築し、対応する値が存在しない場合はNaNを挿入します。
アップサンプリングの例: 日次データを12時間ごとのデータに
日次のデータを12時間ごとのデータにアップサンプリングしてみましょう。
# サンプルデータの再作成 (時間データを含む)
index_hourly = pd.date_range('2024-01-01 00:00', periods=10, freq='H')
data_hourly = np.random.randint(1, 10, 10)
df_hourly = pd.DataFrame({'value': data_hourly}, index=index_hourly)
print("元の時間ごとのデータ (一部):\n", df_hourly)
# 12時間ごとのデータに変換
df_12h = df_hourly.asfreq('12H')
print("\n12時間ごとのデータ (NaNを含む可能性):\n", df_12h)
この例では、元のデータが時間ごとであるため、asfreq('12H')とすることで、12時間ごとのインデックスが作成され、対応するデータがない箇所はNaNになります。
欠損値の補間
asfreqで発生したNaNを補間したい場合は、fillna(), bfill(), ffill()などのメソッドを組み合わせて使用します。
-
ffill(): 前の有効な値で補間(forward fill) -
bfill(): 後ろの有効な値で補間(backward fill)
# NaNを前の値で補間
df_12h_ffill = df_hourly.asfreq('12H').ffill()
print("\n12時間ごとのデータ (ffillで補間):\n", df_12h_ffill)
asfreqとresampleの使い分け
-
resample:-
集計操作が必要な場合(合計、平均、最大、最小など)
-
主にダウンサンプリングに適している
-
期間内のデータがどのように扱われるかを柔軟に制御したい場合
-
-
asfreq:-
特定の頻度でインデックスを再構築したい場合
-
欠損値を
NaNで埋めるだけの場合(集計は行わない) -
主にアップサンプリングに適している(特に
NaNを補間する場合)
-
要するに、データを集約して計算したいならresample、**データの頻度を調整して欠損値を管理したいならasfreq**と考えると良いでしょう。
まとめ
本記事では、Pandasの時系列データ操作における強力なメソッドであるresampleとasfreqについて解説しました。
-
resample: 時系列データを指定した時間間隔でグループ化し、様々な集計処理(sum,meanなど)を行う際に使用します。主にダウンサンプリングで利用されます。 -
asfreq: 時系列データの頻度を単純に変更し、新しい頻度に対応する値がない場合はNaNで埋めます。主にアップサンプリングや、特定の頻度でのデータ抽出に利用されます。
これらのメソッドを使いこなすことで、時系列データの分析がより効率的かつ柔軟に行えるようになります。ぜひ、ご自身のデータで試してみてください。

