私はPandas DataFrameに時系列を持っています。タイムスタンプは不均等(1〜5分ごと)ですが、5分ごとに1つ(タイムスタンプは0,5,10,15,20,25,30,35,40,45,50で終了するタイムスタンプが常にあります) 、55)。Python - 時間加重平均パンダ、時間間隔でグループ化
例:
2017-01-01 2:05:00 32.90
2017-01-01 2:07:30 29.83
2017-01-01 2:10:00 45.76
2017-01-01 2:15:00 16.22
2017-01-01 2:20:00 17.33
2017-01-01 2:25:00 23.40
2017-01-01 2:28:45 150.12
2017-01-01 2:30:00 100.29
2017-01-01 2:35:00 38.45
2017-01-01 2:40:00 67.12
2017-01-01 2:45:00 20.00
2017-01-01 2:50:00 58.41
2017-01-01 2:55:00 58.32
2017-01-01 3:00:00 59.89
私は15分のブロックの時間加重平均値を取得したいです。
Group 1 (interval 2017-01-01 2:00:00):
2017-01-01 2:05:00 32.90
2017-01-01 2:07:30 29.83
2017-01-01 2:10:00 45.76
2017-01-01 2:15:00 16.22
Group 2 (interval 2017-01-01 2:15:00):
2017-01-01 2:20:00 17.33
2017-01-01 2:25:00 23.40
2017-01-01 2:28:45 150.12
2017-01-01 2:30:00 100.29
Group 3 (interval 2017-01-01 2:30:00):
2017-01-01 2:35:00 38.45
2017-01-01 2:40:00 67.12
2017-01-01 2:45:00 20.00
Group 4 (interval 2017-01-01 2:45:00):
2017-01-01 2:50:00 58.41
2017-01-01 2:55:00 58.32
2017-01-01 3:00:00 59.89
平均でなければなりません:間隔の終了15分マーク(0,15,30,45で終わる分とタイムスタンプ)の上に直接あるので、次のようにグループ化されたタイムスタンプを持つ行時間加重値なので、グループ内のすべての値の標準平均値だけではありません。
たとえば、グループ2の時間加重平均は72.785ではなく、4つの値のすべての正規平均です。むしろ、それは次のようになります。
(5 minutes/15 minutes) * 17.33 = 5.776667 ==> The 5 minutes is taken from the difference between this timestamp and the previous timestamp
+(5 minutes/15 minutes) * 23.40 = 7.8
+(3.75 minutes/15 minutes) * 150.12 = 37.53
+(1.25 minutes/15 minutes) * 100.29 = 8.3575
= **59.46417**
また理想的には、これは60分(時間給)に将来的に変更される可能性がありますよう15分は、パラメータ化され、私は、これはここでの問題はないと思います。
また、パフォーマンスはこれで非常に重要です。私のデータセットは約10k行になるので、各レコードを1つずつ繰り返していくのはかなり遅いでしょう。
私はPandasのdf.rolling()関数を調べてみましたが、特定のシナリオに直接適用する方法を理解できませんでした。
ありがとうございました!
UPDATE 1:サイモンの華麗なソリューションに続き
、私はそれを少し変更しました。
私は私の特定の場合に適合させるためにそれにいくつかの調整をした:
def func(df):
if df.size == 0: return
timestep = 15*60
indexes = df.index - (df.index[-1] - pd.Timedelta(seconds=timestep))
seconds = indexes.seconds
weight = [seconds[n]/timestep if n == 0 else (seconds[n] - seconds[n - 1])/timestep
for n, k in enumerate(seconds)]
return np.sum(weight*df.values)
これは、この1だった空の可能性が15分間隔(DBで欠落行)
これは素晴らしいです!ありがとう、これは私が必要としていたものです! Resample()の代わりにGroupBy()を使用する方法はありますか? 理由は、グループ化したい別の列がありますが、単純化のために元の質問には含めませんでした。私は使用するテーブルのようです: df.groupby([pd.TimeGrouper(freq = '15Min')]) しかし、右側のグループを閉じる方法はないようですresample()関数が持っています。 –
だから基本的に、私は私のテーブルに次の4列があります「| ZONE | PRICE1 | TIME PRICE2」 をそして私は私がした各価格 –
ための時間加重ゾーンごとの平均値と15分間隔ごとを持ちたいですより多くのデータとより多くのテストは非常に遅いです。多分私はPythonの速度に慣れていないかもしれません。 160万行(~3行ずつの530kグループ)を処理するには、約10分かかりました。 C#プログラムでも同じことをしました(各行で手作業で反復しなければならないため、コードはずっと長くなりました)、10秒以下でした。 –