Luc*_*ess 6 python time-series multi-index dataframe pandas
我有一些时间序列数据作为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
Run Code Online (Sandbox Code Playgroud)
使用方法1,我遇到的问题是我的布尔选择操作似乎没有按预期工作.例如
weather_test = weather[weather['parsed_time'].dt.minute == (15 & 45)]
Run Code Online (Sandbox Code Playgroud)
给出parsed_time值,如下所示:
2018-04-15 14:13:00
2018-04-15 15:13:00
weather_test = weather[weather['parsed_time'].dt.minute == (15 | 45)]
Run Code Online (Sandbox Code Playgroud)
结果是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
Run Code Online (Sandbox Code Playgroud)
等等.
使用方法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)
Run Code Online (Sandbox Code Playgroud)
最终得到一个如下所示的数据框:
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
Run Code Online (Sandbox Code Playgroud)
请注意,观测结果的变化时间为每30分钟:15过去和过去45分钟到每分钟(例如:01,:02,:14等),并且它也因站而异 - 并非所有站都有每次观察.
我试过这个:
weather_test = weather.resample('30min', level=1).mean()
Run Code Online (Sandbox Code Playgroud)
但是这个重新采样没有偏移,也摆脱了多索引中的站级别.
期望的结果是:
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
Run Code Online (Sandbox Code Playgroud)
其中每分钟的观察结果被重新采样为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
Run Code Online (Sandbox Code Playgroud)
groupby您可以使用和的组合resample:
res = weather.groupby('Station').resample('30min').mean().reset_index('Station')
Run Code Online (Sandbox Code Playgroud)
默认情况下,resample选择 bin 间隔[16:00, 16:30)和[16:30, 17:00)。正如您已经注意到的,时间索引在没有偏移的情况下重新采样,但您可以使用以下命令将其添加回来DateOffset:
res.index = res.index + pd.DateOffset(minutes=15)
Run Code Online (Sandbox Code Playgroud)
产生:
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
Run Code Online (Sandbox Code Playgroud)
或者,您可以直接在重采样方法中指定偏移量:
weather.groupby('Station').resample('30min', loffset=pd.Timedelta('15min')).mean()
Run Code Online (Sandbox Code Playgroud)