Pandas時系列データを15分と45分にリサンプリング-マルチインデックスまたは列を使用
私はいくつかの時系列データをa Pandasデータフレームとして1時間15分と45分(30分間隔の時間間隔)の観測で開始し、頻度を1分ごとに変更します。データを再サンプリングして、データフレーム全体に対して、過去15時間と45時間で、30分ごとの定期的な頻度になるようにします。
これを達成するための2つの方法を考えました。
1。時系列データをデータフレームの列として使用して、15分と45分ですべての観測のデータフレームをフィルターするだけです。
2。時系列データがマルチインデックスの一部になるようにインデックスを再設定し(インデックスの0番目のレベルは気象台で、1番目のレベルは観測の時間です)、Pandas resample()
などの日時timeseries機能。
元のデータフレームである天気は次のようになります。
parsed_time Pressure Temp Hum
Station (index)
Bow 1 2018-04-15 14:15:00 1012 20.0 87
2 2018-04-15 14:45:00 1013 20.0 87
3 2018-04-15 15:15:00 1012 21.0 87
4 2018-04-15 15:45:00 1014 22.0 86
5 2018-04-15 16:00:00 1015 22.0 86
6 2018-04-15 16:01:00 1012 25.0 86
7 2018-04-15 16:02:00 1012 25.0 86
Stratford 8 2018-04-15 14:15:00 1011 18.0 87
9 2018-04-15 14:45:00 1011 18.0 87
10 2018-04-15 15:15:00 1012 18.0 87
11 2018-04-15 15:45:00 1014 19.0 86
12 2018-04-15 16:00:00 1014 19.0 86
13 2018-04-15 16:01:00 1015 19.0 86
14 2018-04-15 16:02:00 1016 20.0 86
15 2018-04-15 16:04:00 1016 20.0 86
方法1では、ブール選択操作が期待どおりに動作しないように見えるという問題があります。例えば
weather_test = weather[weather['parsed_time'].dt.minute == (15 & 45)]
次のようなparsed_time値を提供します:
2018-04-15 14:13:00
2018-04-15 15:13:00
weather_test = weather[weather['parsed_time'].dt.minute == (15 | 45)]
結果は次のようなparsed_time値になります:
2018-04-15 14:47:00
2018-04-15 14:47:00
ドキュメントでこの動作を説明するものは見つかりません。私が欲しいのは、次の時間におけるステーション別の圧力、温度、湿度です。
2018-04-15 14:45:00
2018-04-15 15:15:00
2018-04-15 15:45:00
2018-04-15 16:15:00
等々。
方法2では、分単位のデータがある観測値が直前の30分の平均値に置き換えられるように、データをリサンプリングすることを考えました。この機能は、parsed_time列がインデックスの一部である場合にのみ機能するようです。そのため、次のコードを使用して、parsed_timeをマルチインデックスの一部として設定しました。
weather.set_index('parsed_time', append=True, inplace=True)
weather.index.set_names('station', level=0, inplace=True)
weather = weather.reset_index(level=1, drop=True)
最終的には次のようなデータフレームになります。
Pressure Temp Hum
Station parsed_time
Bow 2018-04-15 14:15:00 1012 20.0 87
2018-04-15 14:45:00 1013 20.0 87
2018-04-15 15:15:00 1012 21.0 87
2018-04-15 15:45:00 1014 22.0 86
2018-04-15 16:00:00 1015 22.0 86
2018-04-15 16:01:00 1012 25.0 86
2018-04-15 16:02:00 1012 25.0 86
Stratford 2018-04-15 14:15:00 1011 18.0 87
2018-04-15 14:45:00 1011 18.0 87
2018-04-15 15:15:00 1012 18.0 87
2018-04-15 15:45:00 1014 19.0 86
2018-04-15 16:00:00 1014 19.0 86
2018-04-15 16:01:00 1015 19.0 86
2018-04-15 16:02:00 1016 20.0 86
2018-04-15 16:04:00 1016 20.0 86
観測値のサンプリングは、過去15時と45時の30分ごとから毎分まで変化します(例:01、:02、:14など)。また、測点によっても異なります。すべての測点にすべての観測があるわけではありません。
私はこれを試しました:
weather_test = weather.resample('30min', level=1).mean()
しかし、これはオフセットなしでリサンプリングし、マルチインデックスの測点レベルも取り除きます。
望ましい結果はこれです:
Pressure Temp Hum
Station parsed_time
Bow 2018-04-15 14:15:00 1012 20.0 87
2018-04-15 14:45:00 1013 20.0 87
2018-04-15 15:15:00 1012 21.0 87
2018-04-15 15:45:00 1014 22.0 86
2018-04-15 16:15:00 1013 24.0 86
Stratford 2018-04-15 14:15:00 1011 18.0 87
2018-04-15 14:45:00 1011 18.0 87
2018-04-15 15:15:00 1012 18.0 87
2018-04-15 15:45:00 1014 19.0 86
2018-04-15 16:15:00 1015 19.5 86
1分ごとの観測値が、毎時15分と45分の30分間隔の平均としてリサンプリングされています。
ステーションをマルチインデックスのレベルとして維持することは不可欠です。値は各ステーションで繰り返されるため(それは一意ではないため)、時間インデックスをそれ自体のインデックスとして使用することはできません。
しばらくの間、私はこれを一周しているので、すべての助けに感謝します。ありがとう!
私はこれまでにかなりの数の以前の投稿を見てきました: Pythonのデータフレームのタイムスタンプ値を使用したブールフィルター
日時列を最も近い15分に丸める方法
and: リサンプリングa pandasマルチインデックスを含むtimeseriesを含むデータフレーム これは、かなり単純なものに対して少し複雑に思われます...
とドキュメント: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.resample.html ありがとうございます!
2番目の最後のデータフレームから開始します(weather.reset_index(Station, inplace=True)
を使用した後):
Station Pressure Temp Hum
parsed_time
2018-04-15 14:15:00 Bow 1012.0 20.0 87.0
2018-04-15 14:45:00 Bow 1013.0 20.0 87.0
2018-04-15 15:15:00 Bow 1012.0 21.0 87.0
2018-04-15 15:45:00 Bow 1014.0 22.0 86.0
2018-04-15 16:00:00 Bow 1015.0 22.0 86.0
2018-04-15 16:01:00 Bow 1012.0 25.0 86.0
2018-04-15 16:02:00 Bow 1012.0 25.0 86.0
2018-04-15 14:15:00 Stratford 1011.0 18.0 87.0
2018-04-15 14:45:00 Stratford 1011.0 18.0 87.0
2018-04-15 15:15:00 Stratford 1012.0 18.0 87.0
2018-04-15 15:45:00 Stratford 1014.0 19.0 86.0
2018-04-15 16:00:00 Stratford 1014.0 19.0 86.0
2018-04-15 16:01:00 Stratford 1015.0 19.0 86.0
2018-04-15 16:02:00 Stratford 1016.0 20.0 86.0
2018-04-15 16:04:00 Stratford 1016.0 20.0 86.0
groupby
とresample
の組み合わせを使用できます:
res = weather.groupby('Station').resample('30min').mean().reset_index('Station')
デフォルトでは、resample
はビンの間隔を選択します[16:00, 16:30)
および[16:30, 17:00)
。既にお気づきのとおり、時間インデックスはオフセットなしでリサンプリングされますが、後でDateOffset
を使用して追加できます。
res.index = res.index + pd.DateOffset(minutes=15)
これにより、
Station Pressure Temp Hum
parsed_time
2018-04-15 14:15:00 Bow 1012.00 20.0 87.0
2018-04-15 14:45:00 Bow 1013.00 20.0 87.0
2018-04-15 15:15:00 Bow 1012.00 21.0 87.0
2018-04-15 15:45:00 Bow 1014.00 22.0 86.0
2018-04-15 16:15:00 Bow 1013.00 24.0 86.0
2018-04-15 14:15:00 Stratford 1011.00 18.0 87.0
2018-04-15 14:45:00 Stratford 1011.00 18.0 87.0
2018-04-15 15:15:00 Stratford 1012.00 18.0 87.0
2018-04-15 15:45:00 Stratford 1014.00 19.0 86.0
2018-04-15 16:15:00 Stratford 1015.25 19.5 86.0
または、resampleメソッドで直接オフセットを指定することもできます。
weather.groupby('Station').resample('30min', loffset=pd.Timedelta('15min')).mean()
私はあなたのデータを持っていないのでこれを直接調べることはできませんが、オプション1として参照するオプションに対して次の構文を試してください。
weather_test = weather[(weather['parsed_time'].dt.minute == 15) | (weather['parsed_time'].dt.minute == 45)]
インデックスなしで開始する場合(行インデックスを除く)、以下を実行できます。
# Create a rounded timestamp
df['parsed_time_rounded'] = (df['parsed_time'] - pd.Timedelta('15min')).dt.round('30min') + pd.Timedelta('15min')
# Group by the station, and the rounded timestamp instead of the raw timestamp
df.groupby(['Station', 'parsed_time_rounded']).mean()