簡體   English   中英

Pandas將時間序列數據重新采樣到15分鍾和45分鍾 - 使用多索引或列

[英]Pandas resample timeseries data to 15 mins and 45 mins - using multi-index or column

我有一些時間序列數據作為Pandas數據幀,從一小時后15分鍾和過去45分鍾(30分鍾的時間間隔)開始觀察,然后將頻率改變為每分鍾。 我想對數據進行重新采樣,使其在整個數據幀的每小時30分鍾,15小時和45小時的常規頻率。

我想到了實現這個目標的兩種方法。
1.使用時間序列數據作為數據幀中的列,只需在15分鍾和45分鍾時過濾所有觀測值的數據幀。
2.重新設置索引,使時間序列數據成為多指標的一部分(索引的第0級是氣象站,第1級是觀察時間)並使用熊貓日期時間序列功能,如resample()

原始數據幀,天氣,如下所示:

                  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

請注意,觀測結果的變化時間為每30分鍾:15過去和過去45分鍾到每分鍾(例如: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

其中每分鍾的觀察結果被重新采樣為30分鍾間隔的平均值:15和45小時。

將站點保持在多指標中的水平是至關重要的。 我不能將時間索引用作索引,因為每個站的值都重復(並且不是唯一的)。

所有的幫助表示贊賞,因為我已經在這個圈子里轉了一會兒。 謝謝!

我已經看了很多以前的帖子,包括: 在Python中使用數據框上的時間戳值的布爾過濾器
如何將日期時間列舍入到最接近的四分之一小時
和: 使用包含時間序列的多索引對pandas數據幀進行重新采樣 ,對於應該非常簡單的事情看起來有點復雜......

和文檔: http//pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.resample.html謝謝!

從您的第二個最后一個數據幀開始(在使用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

你可以使用groupbyresample的組合:

res = weather.groupby('Station').resample('30min').mean().reset_index('Station')

默認情況下, resample選擇bin間隔[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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM