リサンプリングは、時系列分析において時系列データを処理するための基本的な手法です。これは、時系列データをある周波数から別の周波数に変換することであり、データの時間間隔を変更したり、アップサンプリングを通じて粒度を高めたり、ダウンサンプリングを通じて粒度を減らしたりすることができます。この記事では、Pandas でのリサンプリングの重要な問題について詳しく説明します。
リサンプリングが重要なのはなぜですか?
時系列データは、多くの場合、目的の分析間隔と一致しないタイムスタンプとともに到着します。たとえば、データは不規則な間隔で収集されますが、一貫した頻度でモデル化または分析する必要があります。
リサンプル分類
リサンプリングには主に 2 つのタイプがあります。
1、アップサンプリング
アップサンプリングにより、データの頻度や粒度が向上します。これは、データをより短い時間間隔に変換することを意味します。
2、ダウンサンプリング
ダウンサンプリングには、データの頻度または粒度を減らすことが含まれます。データをより長い時間間隔に変換します。
リサンプリングアプリケーション
リサンプリングには幅広い用途があります。
財務分析では、株価やその他の財務指標が不定期に記録される場合があります。このデータは、取引戦略の時間枠 (日次または週次など) に合わせて調整できます。
モノのインターネット (IoT) デバイスは、さまざまな頻度でデータを生成することがよくあります。リサンプリングにより分析データが正規化され、一貫した時間間隔が保証されます。
時系列ビジュアライゼーションを作成する場合、多くの場合、さまざまな頻度でデータを表示する必要があります。リサンプリングを使用すると、図面の詳細レベルを調整できます。
多くの機械学習モデルは、一定の時間間隔のデータを必要とします。リサンプリングは、モデルのトレーニング用に時系列データを準備するときに不可欠です。
リサンプリングプロセス
リサンプリング プロセスには通常、次の手順が含まれます。
まず、リサンプリングする時系列データを選択します。このデータは、数値、テキスト、カテゴリデータなど、さまざまな形式にすることができます。
データをリサンプリングする頻度を決定します。これには、粒度を増やす (アップサンプリング) ことも、粒度を減らす (ダウンサンプリング) こともできます。
リサンプリング方法を選択します。一般的な方法には、平均化、合計、またはデータ内のギャップを埋めるための内挿技術の使用が含まれます。
アップサンプリングすると、元のタイムスタンプ間のデータ ポイントが欠落する場合があります。線形または三次スプライン補間などの補間方法を使用して、これらの値を推定できます。
ダウンサンプリングの場合、データ ポイントは通常、各ターゲット間隔内で集約されます。一般的な集計関数には、合計、平均、中央値などがあります。
リサンプリングされたデータを評価して、分析の目的を満たしていることを確認します。データの一貫性、完全性、正確性をチェックします。
Pandas の resample() メソッド
resample は、Pandas シリーズ オブジェクトと DataFrame オブジェクトの両方で操作できます。時系列データの集計、変換、ダウンサンプリングとアップサンプリングなどの操作を実行するために使用されます。
以下であり
resample()
メソッドの基本的な使用法といくつかの共通パラメータ:
import pandas as pd
# 创建一个示例时间序列数据框
data = {'date': pd.date_range(start='2023-01-01', end='2023-12-31', freq='D'),
'value': range(365)}
df = pd.DataFrame(data)
# 将日期列设置为索引
df.set_index('date', inplace=True)
# 使用resample()方法进行重新采样
# 将每日数据转换为每月数据并计算每月的总和
monthly_data = df['value'].resample('M').sum()
# 将每月数据转换为每季度数据并计算每季度的平均值
quarterly_data = monthly_data.resample('Q').mean()
# 将每季度数据转换为每年数据并计算每年的最大值
annual_data = quarterly_data.resample('Y').max()
print(monthly_data)
print(quarterly_data)
print(annual_data)
上の例では、最初にサンプル時系列データ フレームを作成し、
resample()
メソッドは、それをさまざまな時間頻度 (月ごと、四半期ごと、年ごと) に変換し、さまざまな集計関数 (合計、平均、最大) を適用します。
resample()
メソッドパラメータ:
- 最初のパラメータは、リサンプリングのターゲット周波数を指定する時間周波数文字列です。一般的なオプションには
'D'
、(毎日)、'M'
(毎月)、'Q'
(四半期)、'Y'
(毎年) などが含まれます。 - 、など
how
の2 番目のパラメータを使用して集計関数を指定できます。デフォルトは です。'sum'
'mean'
'max'
'mean'
closed
パラメーターを使用して、各間隔の閉じたエンドポイントを指定することもできます。オプションの値には'right'
、'left'
、 が'both'
含まれ'neither'
、デフォルトは です'right'
。- パラメータを使用して、リサンプリングされたラベルに使用するタイムスタンプを指定します。オプションの値には、、 が
label
含まれ、デフォルトは です。'right'
'left'
'both'
'neither'
'right'
- パラメータを使用して、
loffset
リサンプリングされたタイムスタンプのオフセットを調整できます。 'sum'
最後に、関数の引数など、集計関数の特定のパラメーターを使用して、min_count
非 NA 値の最小数を指定できます。
1. カラム名の指定
デフォルトでは、Pandas の resample() メソッドは、Time 型である必要がある Dataframe または Series のインデックスを使用します。ただし、特定の列に基づいてリサンプリングする場合は、on パラメーターを使用できます。これにより、インデックスでない場合でも、リサンプリング用に特定の列を選択できます。
df.reset_index(drop=False, inplace=True)
df.resample('W', on='index')['C_0'].sum().head()
このコードでは、 resample() メソッドを使用して 'index' 列に対して毎週のリサンプリングが実行され、'C_0' 列の毎週の合計が計算されます。
2. 開始時間と終了時間の間隔を指定します。
閉じたパラメータを使用すると、リサンプリング中の開始間隔と終了間隔を制御できます。デフォルトでは、「M」、「A」、「Q」、「BM」、「BA」、「BQ」、「W」などの一部の周波数は右閉じです。つまり、右側の境界が含まれますが、他の周波数は右閉です。左端を含む左閉じ。データ周波数を変換する場合、必要に応じてオフ間隔を手動で設定できます。
df = generate_sample_data_datetime()
pd.concat([df.resample('W', closed='left')['C_0'].sum().to_frame(name='left_closed'),
df.resample('W', closed='right')['C_0'].sum().to_frame(name='right_closed')],
axis=1).head(5)
このコードでは、日次頻度を週次頻度に変換するときの、左側の閉間隔と右側の閉間隔の違いを示します。
3. 出力結果の制御
label パラメーターは、リサンプリング中の出力結果のラベルを制御できます。デフォルトでは、一部の周波数は出力ラベルとしてグループ内の右側の境界を使用し、他の周波数は左側の境界を使用します。データ頻度を変換するときに、出力ラベルとして左側または右側の境界を使用するかどうかを指定できます。
df = generate_sample_data_datetime()
df.resample('W', label='left')['C_0'].sum().to_frame(name='left_boundary').head(5)
df.resample('W', label='right')['C_0'].sum().to_frame(name='right_boundary').head(5)
このコードでは、label パラメータに「left」を指定するか「right」を指定するかによって出力ラベルが変わりますが、実際のアプリケーションでは混乱を避けるために明示的に指定することを推奨します。
4. 要約統計量
リサンプリングでは、groupby を使用する場合と同様に、集計統計を実行できます。合計、平均、最小、最大などの集計方法を使用して、リサンプリング間隔内のデータを要約します。これらの集計方法は、groupby 操作で使用できるものと似ています。
df.resample('D').sum()
df.resample('W').mean()
df.resample('M').min()
df.resample('Q').max()
df.resample('Y').count()
df.resample('W').std()
df.resample('M').var()
df.resample('D').median()
df.resample('M').quantile([0.25, 0.5, 0.75])
custom_agg = lambda x: x.max() - x.min()
df.resample('W').apply(custom_agg)
アップサンプリングとパディング
時系列データ分析では、アップサンプリングとダウンサンプリングは、データ観測の頻度を操作するために使用される手法です。これらの手法は、分析ニーズに合わせて時系列データの粒度を調整するのに役立ちます。
まずデータを生成しましょう
import pandas as pd
import numpy as np
def generate_sample_data_datetime():
np.random.seed(123)
number_of_rows = 365 * 2
num_cols = 5
start_date = '2023-09-15' # You can change the start date if needed
cols = ["C_0", "C_1", "C_2", "C_3", "C_4"]
df = pd.DataFrame(np.random.randint(1, 100, size=(number_of_rows, num_cols)), columns=cols)
df.index = pd.date_range(start=start_date, periods=number_of_rows)
return df
df = generate_sample_data_datetime()
アップサンプリングにはデータの粒度を高めることが含まれます。これは、データを低周波数から高周波数に変換することを意味します。
上記で生成された日次データがあり、それを 12 時間の頻度に変換し、各間隔の「C_0」の合計を計算したいとします。
df.resample('12H')['C_0'].sum().head(10)
このコードは、データを 12 時間間隔にリサンプリングし、各間隔内の 'C_0' に合計集計を適用します。この .head(10) は、結果の最初の 10 行を表示するために使用されます。
アップサンプリング プロセス中、特に低い周波数から高い周波数に変換する場合、新しい周波数によって生じたギャップによりデータ ポイントの欠落が発生することがあります。そのため、ギャップデータを埋める必要があり、一般的に次のような方法で埋められます。
前方埋め込み - 欠落している値を以前の使用可能な値で埋めます。前方パディングの量は、limit パラメーターを使用して制限できます。
df.resample('8H')['C_0'].ffill(limit=1)
バックフィル - 欠損値を次に利用可能な値で埋めます。
df.resample('8H')['C_0'].bfill(limit=1)
最近の埋め込み - 欠落しているデータを最も近い利用可能な値で埋めます。値は前方または後方に設定できます。
df.resample('8H')['C_0'].nearest(limit=1)
Fillna — 前の 3 つのメソッドの機能を組み合わせたものです。方法 ('pad'/'fill'、'bfill'、'nearest' など) を指定し、数量制御に制限パラメーターを使用できます。
df.resample('8H')['C_0'].fillna(method='pad', limit=1)
Asfreq - 固定値を指定して、欠落部分をすべて 1 回で埋めます。たとえば、-999 を使用して欠損値を埋めることができます。
df.resample('8H')['C_0'].asfreq(-999)
補間方法 - さまざまな補間アルゴリズムを適用できます。
df.resample('8H').interpolate(method='linear').applymap(lambda x: round(x, 2))
よく使用されるいくつかの関数
1. 集計には agg を使用します
result = df.resample('W').agg(
{
'C_0': ['sum', 'mean'],
'C_1': lambda x: np.std(x, ddof=1)
}
).head()
agg メソッドを使用して、日次の時系列データを週次の頻度にリサンプリングします。また、列ごとに異なる集計関数を指定します。「C_0」の場合は合計と平均が計算され、「C_1」の場合は標準偏差が計算されます。
2. 適用集計を使用する
def custom_agg(x):
agg_result = {
'C_0_mean': round(x['C_0'].mean(), 2),
'C_1_sum': x['C_1'].sum(),
'C_2_max': x['C_2'].max(),
'C_3_mean_plus1': round(x['C_3'].mean() + 1, 2)
}
return pd.Series(agg_result)
result = df.resample('W').apply(custom_agg).head()
Custom_agg と呼ばれるカスタム集計関数が定義されており、DataFrame x を入力として受け取り、さまざまな列でさまざまな集計を計算します。apply メソッドを使用してデータを毎週の頻度でリサンプリングし、カスタム集計関数を適用します。
3. 変換を使用して変換します
df['C_0_cumsum'] = df.resample('W')['C_0'].transform('cumsum')
df['C_0_rank'] = df.resample('W')['C_0'].transform('rank')
result = df.head(10)
変換メソッドを使用して、週次グループ内の変数「C_0」の累積合計ランキングを計算します。DF の元のインデックス構造は変更されません。
4. パイプライン操作にパイプを使用する
result = df.resample('W')['C_0', 'C_1'] \
.pipe(lambda x: x.cumsum()) \
.pipe(lambda x: x['C_1'] - x['C_0'])
result = result.head(10)
パイプライン方式を使用して、ダウンサンプリングされた「C_0」変数と「C_1」変数をチェーンします。Cumsum 関数は累積合計を計算し、2 番目のパイプライン操作はグループごとに 'C_1' と 'C_0' の差を計算します。パイプラインのように順次操作を実行します。
要約する
時系列のリサンプリングは、時系列データを 1 つの時間頻度 (日次など) から別の時間頻度 (月次または年次など) に変換することであり、通常はデータの集計操作を伴います。リサンプリングは時系列データ処理における重要な操作であり、これによりデータの傾向とパターンをより深く理解できるようになります。
Python では Pandas ライブラリを使用できます
resample()
時系列リサンプリングを実行するメソッド。
https://avoid.overfit.cn/post/cf6fba5f6cbe49619738f2181b1bbd70
著者:JIN