Pandasで時系列差分インデックスの頻度を賢く推測: `pandas.TimedeltaIndex.inferred_freq`徹底解説
pandas.TimedeltaIndex.inferred_freq
は、TimedeltaIndex
オブジェクトの推定頻度を表す文字列を返します。これは、TimedeltaIndex
オブジェクトの値間の差が一定かどうかを判断し、その差に基づいて頻度を推定するものです。
詳細
TimedeltaIndex
オブジェクトは、時系列データの差分を表すデータ構造です。各要素は、前の要素との時間差を表す timedelta
オブジェクトです。inferred_freq
属性は、この差分に基づいて推定される頻度を表します。
推定頻度の種類
推定される頻度は、以下のいずれかになります。
'ns'
: すべての差分が 1 ナノ秒の場合'U'
: すべての差分が 1 マイクロ秒の場合'L'
: すべての差分が 1 ミリ秒の場合'S'
: すべての差分が 1 秒の場合'T'
: すべての差分が 1 分の場合'H'
: すべての差分が 1 時間の場合'D'
: すべての差分が 1 日の場合'B'
: すべての差分が 1 ビジネスデーの場合'N'
: すべての差分が同じ場合 (N
は差分の値)None
: 頻度を推定できない場合
推定頻度の判断
inferred_freq
属性は、以下の手順で推定されます。
- すべての差分が同じかどうかを確認します。同じ場合は、その値を
N
として返します。 - すべての差分が 1 ビジネスデーかどうかを確認します。同じ場合は、
'B'
を返します。 - すべての差分が 1 日かどうかを確認します。同じ場合は、
'D'
を返します。 - ... (同様の手順で
'H'
,'T'
,'S'
,'L'
,'U'
,'ns'
を確認) - 上記のいずれにも該当しない場合は、
None
を返します。
例
import pandas as pd
# 1 日おきの時間差の TimedeltaIndex を作成
tdidx = pd.TimedeltaIndex([pd.Timedelta('1 days'), pd.Timedelta('2 days'), pd.Timedelta('3 days')])
# 推定頻度を取得
print(tdidx.inferred_freq)
このコードを実行すると、以下の出力が得られます。
D
これは、TimedeltaIndex
オブジェクトのすべての差分が 1 日であるため、推定頻度が 'D'
になることを意味します。
異なる頻度の TimedeltaIndex を作成
import pandas as pd
# 1 日おきの時間差の TimedeltaIndex
tdidx1 = pd.TimedeltaIndex([pd.Timedelta('1 days'), pd.Timedelta('2 days'), pd.Timedelta('3 days')])
# 12 時間おきの時間差の TimedeltaIndex
tdidx2 = pd.TimedeltaIndex([pd.Timedelta('12 hours'), pd.Timedelta('24 hours'), pd.Timedelta('36 hours')])
# 1 分おきの時間差の TimedeltaIndex
tdidx3 = pd.TimedeltaIndex([pd.Timedelta('1 minutes'), pd.Timedelta('2 minutes'), pd.Timedelta('3 minutes')])
# 推定頻度を表示
print(tdidx1.inferred_freq) # 'D'
print(tdidx2.inferred_freq) # 'H'
print(tdidx3.inferred_freq) # 'T'
D
H
T
それぞれの TimedeltaIndex
オブジェクトの推定頻度が、正しく推定されていることが確認できます。
推定頻度が None になる場合
import pandas as pd
# ランダムな時間差の TimedeltaIndex
tdidx = pd.TimedeltaIndex([pd.Timedelta('10 seconds'), pd.Timedelta('2 minutes'), pd.Timedelta('3 hours')])
# 推定頻度を表示
print(tdidx.inferred_freq)
None
これは、TimedeltaIndex
オブジェクトの差分がランダムなため、推定頻度を特定できないことを意味します。
import pandas as pd
# 1 日おきの時間差の TimedeltaIndex
tdidx = pd.TimedeltaIndex([pd.Timedelta('1 days'), pd.Timedelta('2 days'), pd.Timedelta('3 days')])
# 頻度を 'H' (1 時間) に設定
tdidx = tdidx.to_freq('H')
# 推定頻度を表示
print(tdidx.inferred_freq)
H
より正確な方法として、以下の代替方法を検討することができます。
to_freq() メソッドを使用する
to_freq()
メソッドを使用すると、TimedeltaIndex
オブジェクトの頻度を明示的に設定することができます。
import pandas as pd
# 1 日おきの時間差の TimedeltaIndex
tdidx = pd.TimedeltaIndex([pd.Timedelta('1 days'), pd.Timedelta('2 days'), pd.Timedelta('3 days')])
# 頻度を 'H' (1 時間) に設定
tdidx = tdidx.to_freq('H')
# 各要素の時間差を取得
print(tdidx.hour)
0 0 0
Name: hour, dtype: int64
to_freq()
メソッドを使用すると、推定ではなく、設定した値に基づいた正確な頻度を取得することができます。
df.diff() メソッドと df.dropna() メソッドを使用する
df.diff()
メソッドと df.dropna()
メソッドを使用して、差分と欠損値を除去することで、頻度を推定することができます。
import pandas as pd
# ランダムな時間差の TimedeltaIndex
tdidx = pd.TimedeltaIndex([pd.Timedelta('10 seconds'), pd.Timedelta('2 minutes'), pd.Timedelta('3 hours')])
# 差分を取得
diffs = tdidx.diff()
# 欠損値を除去
diffs = diffs.dropna()
# 最小公倍数を求める
freq = pd.api.types.common.gcd(*diffs)
# 頻度を文字列に変換
freq_str = str(freq).lower() + (freq.unit if freq.unit else '')
# 推定頻度を表示
print(freq_str)
2m
この方法は、推定頻度だけでなく、最小公倍数である正確な頻度を取得することができます。
pd.Series と to_timedelta() メソッドを使用する
pd.Series
と to_timedelta()
メソッドを使用して、TimedeltaIndex
オブジェクトを作成し、その頻度を取得することができます。
import pandas as pd
# ランダムな時間差のリスト
time_diffs = [pd.Timedelta('10 seconds'), pd.Timedelta('2 minutes'), pd.Timedelta('3 hours')]
# Series に変換
s = pd.Series(time_diffs)
# TimedeltaIndex に変換
tdidx = s.to_timedelta()
# 頻度を取得
freq = tdidx.inferred_freq
# 頻度を文字列に変換
freq_str = str(freq).lower() + (freq.unit if freq.unit else '')
# 推定頻度を表示
print(freq_str)
この方法は、TimedeltaIndex
オブジェクトを作成してから inferred_freq
属性を使用するため、to_freq()
メソッドと同様に、推定ではなく設定した値に基づいた正確な頻度を取得することができます。
pandas.TimedeltaIndex.inferred_freq
は推定値であるため、より正確な頻度を取得したい場合は、to_freq()
メソッド、df.diff()
メソッドと df.dropna()
メソッド、pd.Series
と to_timedelta()
メソッドなどの代替方法を検討することをおすすめします。