Pandasで時間軸データを自在に操る!resampleとdt.roundを使いこなそう
PandasのSeries
オブジェクトに含まれる日時データに対して、指定した周波数に基づいて丸めを行うメソッドです。例えば、秒単位で記録された株価データを1分単位で丸めたり、月単位で記録された気温データを年単位で丸めたりすることができます。
構文
Series.dt.round(freq)
引数
freq
: 丸めを行う周波数を指定します。有効な値は以下の通りです。"S"
: 秒"T"
: 分"H"
: 時間"D"
: 日"W"
: 週"M"
: 月"Q"
: 四半期"A"
: 年
例
import pandas as pd
# サンプルデータを作成
data = pd.Series([pd.Timestamp('2023-01-01 09:10:15'), pd.Timestamp('2023-01-01 09:12:34'), pd.Timestamp('2023-01-01 09:15:00')], name='timestamp')
# 1分単位で丸める
result = data.dt.round('T')
print(result)
0 2023-01-01 09:10:00
1 2023-01-01 09:12:00
2 2023-01-01 09:15:00
Name: timestamp, dtype: datetime64[ns]
- 夏時間 (DST) における処理は、
nonexistent
とambiguous
オプションを使用して制御できます。 - タイムゾーン情報が設定されている場合、丸めは現地時間に基づいて行われます。
import pandas as pd
import matplotlib.pyplot as plt
# サンプルデータを作成
data = pd.DataFrame({
'date': pd.to_datetime(['2023-01-01 09:10:15', '2023-01-01 09:12:34', '2023-01-01 09:15:00', '2023-01-01 09:17:22']),
'price': [100.50, 101.23, 102.45, 101.89]
})
# 1分単位で丸めた株価データ
rounded_price = data['price'].dt.round('T')
# グラフで可視化
plt.figure(figsize=(10, 6))
plt.plot(data['date'], data['price'], label='元データ')
plt.plot(data['date'], rounded_price, label='1分単位で丸めたデータ')
plt.legend()
plt.xlabel('時間')
plt.ylabel('株価')
plt.title('秒単位の株価データを1分単位で丸める')
plt.show()
例2:月単位の気温データを年単位で丸める
import pandas as pd
# サンプルデータを作成
data = pd.Series([10.2, 7.8, 5.6, 9.3, 12.5, 15.7, 18.4, 16.2, 13.9, 11.1, 8.5, 6.3], index=pd.to_datetime(['2020-01', '2020-02', '2020-03', '2020-04', '2020-05', '2020-06', '2020-07', '2020-08', '2020-09', '2020-10', '2020-11', '2020-12']))
# 年単位で丸めた気温データ
rounded_temp = data.dt.round('A')
# 結果を表示
print(rounded_temp)
出力
2020-01-01 10.0
2020-02-01 8.0
2020-03-01 6.0
2020-04-01 9.0
2020-05-01 12.0
2020-06-01 16.0
2020-07-01 18.0
2020-08-01 16.0
2020-09-01 14.0
2020-10-01 11.0
2020-11-01 8.0
2020-12-01 6.0
dtype: float64
例3:夏時間 (DST) における処理
import pandas as pd
# サンプルデータを作成
data = pd.Series([pd.Timestamp('2023-03-12 01:00:00'), pd.Timestamp('2023-03-12 02:00:00'), pd.Timestamp('2023-03-12 03:00:00')], name='timestamp')
# 1時間単位で丸める
result = data.dt.round('H', nonexistent='shift_forward', ambiguous='raise')
print(result)
0 2023-03-12 01:00:00
1 2023-03-12 03:00:00
Name: timestamp, dtype: datetime64[ns]
- Pandasの公式ドキュメントには
- 上記の例はあくまで一例です。具体的な用途に合わせて、引数やオプションを変更してください。
以下に、いくつかの代替方法とその利点と欠点をご紹介します。
floor() と ceil() メソッド
- 欠点:
- 指定した周波数よりも粗い丸めしかできない
- 例えば、10分単位で丸めたいのに、
floor()
メソッドだと5分単位でしか丸められない
- 利点:
- シンプルで分かりやすい構文
- 高速に処理できる
# 10分単位で丸める
data['rounded_time'] = data['timestamp'].dt.floor('10T')
resample() メソッド
- 欠点:
dt.round
メソッドよりも処理速度が遅い
- 利点:
- アップサンプリングやダウンサンプリングなど、柔軟な操作が可能
- 欠損値処理を指定できる
# 10分単位で丸める
data = data.resample('10T').mean()
カスタム関数
- 欠点:
- 複雑な処理になる可能性がある
- 処理速度が遅くなる可能性がある
- 利点:
- 独自の丸め処理を実装できる
def round_to_nearest_ten_minutes(timestamp):
# 10分単位の最も近い時刻を計算
rounded_time = timestamp.round('T')
minutes = rounded_time.minute
if minutes % 10 == 0:
pass
elif minutes < 5:
rounded_time -= timedelta(minutes=minutes)
else:
rounded_time += timedelta(minutes=10 - minutes)
return rounded_time
# 10分単位で丸める
data['rounded_time'] = data['timestamp'].apply(round_to_nearest_ten_minutes)
外部ライブラリの利用
- 欠点:
- 別途ライブラリをインストールする必要がある
- 利点:
pandas
にはない機能を利用できる
例えば、dateutil
ライブラリを使用して、10分単位で丸めることができます。
import dateutil.parser
def round_to_nearest_ten_minutes(timestamp_str):
# 文字列から `datetime` オブジェクトに変換
timestamp = dateutil.parser.parse(timestamp_str)
# 10分単位の最も近い時刻を計算
rounded_time = timestamp.round(minute=10)
return rounded_time.strftime('%Y-%m-%d %H:%M:%S')
# 10分単位で丸める
data['rounded_time'] = data['timestamp'].apply(round_to_nearest_ten_minutes)
最適な代替方法の選択
どの代替方法が最適かは、状況によって異なります。
pandas
にはない機能が必要な場合は、外部ライブラリを利用します。- 独自の丸め処理が必要な場合は、カスタム関数を使用します。
- より柔軟な操作が必要な場合は、
resample()
メソッドがおすすめです。 - シンプルで高速な処理が必要な場合は、
floor()
とceil()
メソッドがおすすめです。