首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Pandas将时间序列数据重新采样到15分钟和45分钟-使用多索引或列

Pandas将时间序列数据重新采样到15分钟和45分钟-使用多索引或列
EN

Stack Overflow用户
提问于 2018-08-06 18:30:01
回答 3查看 16.9K关注 0票数 8

我有一些时间序列数据作为Pandas数据帧,它从一小时过15分钟和过去45分钟的观察开始(时间间隔为30分钟),然后将频率更改为每分钟一次。我想对整个数据帧进行重新采样,使其具有每30分钟、过去15分钟和过去45小时的固定频率。

我想到了两种方法来实现这一点。

通过将时间序列数据用作dataframe.

  • Re-set索引中的列,以使时间序列数据成为多个索引的一部分(索引的第0级是气象站,第1级是观测时间),并使用resample().

  1. 时间序列功能,Pandas date-time timeseries功能只需过滤15分钟和45分钟所有观察值的数据帧

原始的数据帧,天气,看起来像这样:

代码语言:javascript
运行
复制
                  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时,我遇到的问题是我的布尔select操作似乎无法按预期工作。例如

代码语言:javascript
运行
复制
weather_test = weather[weather['parsed_time'].dt.minute == (15 & 45)]

给出如下的parsed_time值:

2018-04-15 14:13:00

2018-04-15 15:13:00

代码语言:javascript
运行
复制
weather_test = weather[weather['parsed_time'].dt.minute == (15 | 45)]

结果parsed_time值如下所示:

2018-04-15 14:47:00

2018-04-15 14:47:00

我在文档中找不到任何东西来解释这种行为。我想要的是以下时间的压力,温度,湿度:

代码语言:javascript
运行
复制
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设置为多索引的一部分:

代码语言:javascript
运行
复制
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)

以得到如下所示的数据帧:

代码语言:javascript
运行
复制
                                  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分钟一次,时间间隔为30分钟到每分钟(例如:01、:02、:14等),也因站点而异-并非所有站点都有每个观测值。

我试过这个:

代码语言:javascript
运行
复制
weather_test = weather.resample('30min', level=1).mean()

但这在没有偏移量的情况下进行重采样,并且还去掉了多索引中的桩号级别。

期望的结果是:

代码语言:javascript
运行
复制
                              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分钟间隔内的平均值。

将站点作为多指标中的一个级别是至关重要的。我不能单独使用时间索引作为索引,因为每个站点的值都是重复的(并且不是唯一的)。

所有的帮助都很感谢,因为我已经在这个问题上转了一段时间了。谢谢!

我看过很多以前的帖子,包括:Boolean filter using a timestamp value on a dataframe in Python

How do I round datetime column to nearest quarter hour

还有:Resampling a pandas dataframe with multi-index containing timeseries,对于本应非常简单的东西,它看起来有点复杂……

文档:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.resample.html,谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-07 00:14:07

从倒数第二个数据帧开始(在使用weather.reset_index(Station, inplace=True)之后):

代码语言:javascript
运行
复制
                           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

代码语言:javascript
运行
复制
res = weather.groupby('Station').resample('30min').mean().reset_index('Station')

默认情况下,resample选择bin间隔[16:00, 16:30)[16:30, 17:00)。正如您已经注意到的,时间索引是在没有偏移量的情况下重新采样的,但是您可以在以后使用DateOffset将其添加回来

代码语言:javascript
运行
复制
res.index = res.index + pd.DateOffset(minutes=15)

这会产生:

代码语言:javascript
运行
复制
                           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方法中指定偏移量:

代码语言:javascript
运行
复制
weather.groupby('Station').resample('30min', loffset=pd.Timedelta('15min')).mean()
票数 4
EN

Stack Overflow用户

发布于 2018-08-06 19:51:15

我没有您的数据,所以我不能直接检查它,但是对于您称为选项1的选项,请尝试以下语法:

代码语言:javascript
运行
复制
weather_test = weather[(weather['parsed_time'].dt.minute == 15) | (weather['parsed_time'].dt.minute == 45)]
票数 1
EN

Stack Overflow用户

发布于 2018-08-07 01:02:59

如果开始时没有任何索引(行索引除外),则可以执行以下操作:

代码语言:javascript
运行
复制
# 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()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51705583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档