使用给定的 timedelta 和 binning 或插值对时间序列进行重采样
Resampling timeseries with a given timedelta and binning or interpolation
我有一个简单的时间序列,由日期时间值驱动(也就是说,它定期记录数据点),Series1
:
datetime,temp
2015-05-28 17:00:00,24.199
2015-05-28 17:15:00,24.465
2015-05-28 17:30:00,24.392
2015-05-28 17:45:00,25.094
2015-05-28 18:00:00,25.239
etc.
我正在尝试协调第二个时间序列,它由事件驱动(表示为二进制值 0 和 1),Series2
:
datetime,window
2015-05-28 17:00:00,0.0
2015-05-28 17:55:28,1.0
2015-06-08 07:35:31,0.0
2015-06-08 08:04:30,1.0
2015-06-18 17:11:55,0.0
2015-06-18 18:11:52,1.0
2015-06-19 18:14:09,0.0
etc.
我想协调两者,即将事件驱动的时间序列表示为小时(或亚小时)值。
我假设这可能需要为 Series2
创建一个可以与 Series1
相匹配的日期时间索引,并用 [0,1]
范围内的值填充 window 列。这些值将来自某种 'time binning',其中计算每个间隔花费的时间百分比(间隔由 Series1
中后续行之间的日期时间差异定义)。
希望这是有道理的。
我尝试过使用不同的方法进行重采样,即
series2_hr = series2.resample('H').bfill()
并尝试使用 .mean
和 .last
,但是其中的 none 给了我想要的输出。
我也尝试过插值:
series2_hr = series2.resample('H')
series2_hr = series2_hr.interpolate(method='time')
但还是没有运气。
所需的输出是 window 值为 1 的给定时间间隔(例如每小时)的百分比。换句话说,该小时的 window 的平均值(从 0 到 1).
示例:系列 2
datetime,window
2015-05-28 17:00:00,0.0
2015-05-28 17:55:28,1.0
2015-06-08 07:35:31,0.0
2015-06-08 08:04:30,1.0
2015-06-18 17:11:55,0.0
2015-06-18 18:11:52,1.0
2015-06-19 18:14:09,0.0
etc.
应该转换成series2_reg:
2015-05-28 17:00:00,0.916 (=(17:55 - 17:00)/60)
2015-05-28 18:00:00,1
2015-05-28 19:00:00,1
...
2015-06-08 07:00:00,0.583 (=(07:35 - 07:00)/60))
2015-06-08 08:00:00,0.06 (=(08:04 - 08:00)/60))
2015-06-08 09:00:00,1
2015-06-08 10:00:00,1
...
import io
import pandas as pd
data = io.StringIO('''\
datetime,window
2015-05-28 17:00:00,0.0
2015-05-28 17:55:28,1.0
2015-06-08 07:35:31,0.0
2015-06-08 08:04:30,1.0
2015-06-18 17:11:55,0.0
2015-06-18 18:11:52,1.0
2015-06-19 18:14:09,0.0
''')
s = pd.read_csv(data).set_index('datetime').squeeze()
s.index = pd.to_datetime(s.index)
首先以一分钟为间隔进行上采样,向前填充原始时间序列的条目。
upsampled = s.resample('min').ffill()
upsampled['2015-06-08 07:30':'2015-06-08 08:10']
# datetime
# 2015-06-08 07:30:00 1.0
# 2015-06-08 07:31:00 1.0
# 2015-06-08 07:32:00 1.0
# 2015-06-08 07:33:00 1.0
# 2015-06-08 07:34:00 1.0
# 2015-06-08 07:35:00 1.0
# 2015-06-08 07:36:00 0.0
# 2015-06-08 07:37:00 0.0
# 2015-06-08 07:38:00 0.0
# 2015-06-08 07:39:00 0.0
# 2015-06-08 07:40:00 0.0
# 2015-06-08 07:41:00 0.0
# 2015-06-08 07:42:00 0.0
# 2015-06-08 07:43:00 0.0
# 2015-06-08 07:44:00 0.0
# 2015-06-08 07:45:00 0.0
# 2015-06-08 07:46:00 0.0
# 2015-06-08 07:47:00 0.0
# 2015-06-08 07:48:00 0.0
# 2015-06-08 07:49:00 0.0
# 2015-06-08 07:50:00 0.0
# 2015-06-08 07:51:00 0.0
# 2015-06-08 07:52:00 0.0
# 2015-06-08 07:53:00 0.0
# 2015-06-08 07:54:00 0.0
# 2015-06-08 07:55:00 0.0
# 2015-06-08 07:56:00 0.0
# 2015-06-08 07:57:00 0.0
# 2015-06-08 07:58:00 0.0
# 2015-06-08 07:59:00 0.0
# 2015-06-08 08:00:00 0.0
# 2015-06-08 08:01:00 0.0
# 2015-06-08 08:02:00 0.0
# 2015-06-08 08:03:00 0.0
# 2015-06-08 08:04:00 0.0
# 2015-06-08 08:05:00 1.0
# 2015-06-08 08:06:00 1.0
# 2015-06-08 08:07:00 1.0
# 2015-06-08 08:08:00 1.0
# 2015-06-08 08:09:00 1.0
# 2015-06-08 08:10:00 1.0
# Freq: T, Name: window , dtype: float64
然后按小时重新采样,取每个区间的平均值。
result = upsampled.resample('H').mean()
result['2015-06-08 06:00':'2015-06-08 09:00']
# datetime
# 2015-06-08 06:00:00 1.000000
# 2015-06-08 07:00:00 0.600000
# 2015-06-08 08:00:00 0.916667
# 2015-06-08 09:00:00 1.000000
# Freq: H, Name: window , dtype: float64
请注意,上采样将事件的值分配给具有事件的一分钟。如果您的事件数据表示打开和关闭,这意味着 upsampled
中的每一分钟在该时间段结束时都具有 on/off 开关的状态。这就是为什么我的数字与你的不完全一致(另外,我相信你在 2015-06-08 08:00:00
处的计算有误)。
由于您的事件的粒度精确到秒,您可以按秒而不是按分钟进行上述上采样,从而获得更精确的每小时平均值 window
。
upsampled = s.resample('s').ffill()
result = upsampled.resample('H').mean()
result['2015-06-08 06:00':'2015-06-08 09:00']
# datetime
# 2015-06-08 06:00:00 1.000000
# 2015-06-08 07:00:00 0.591944
# 2015-06-08 08:00:00 0.925000
# 2015-06-08 09:00:00 1.000000
# Freq: H, Name: window , dtype: float64
我有一个简单的时间序列,由日期时间值驱动(也就是说,它定期记录数据点),Series1
:
datetime,temp
2015-05-28 17:00:00,24.199
2015-05-28 17:15:00,24.465
2015-05-28 17:30:00,24.392
2015-05-28 17:45:00,25.094
2015-05-28 18:00:00,25.239
etc.
我正在尝试协调第二个时间序列,它由事件驱动(表示为二进制值 0 和 1),Series2
:
datetime,window
2015-05-28 17:00:00,0.0
2015-05-28 17:55:28,1.0
2015-06-08 07:35:31,0.0
2015-06-08 08:04:30,1.0
2015-06-18 17:11:55,0.0
2015-06-18 18:11:52,1.0
2015-06-19 18:14:09,0.0
etc.
我想协调两者,即将事件驱动的时间序列表示为小时(或亚小时)值。
我假设这可能需要为 Series2
创建一个可以与 Series1
相匹配的日期时间索引,并用 [0,1]
范围内的值填充 window 列。这些值将来自某种 'time binning',其中计算每个间隔花费的时间百分比(间隔由 Series1
中后续行之间的日期时间差异定义)。
希望这是有道理的。
我尝试过使用不同的方法进行重采样,即
series2_hr = series2.resample('H').bfill()
并尝试使用 .mean
和 .last
,但是其中的 none 给了我想要的输出。
我也尝试过插值:
series2_hr = series2.resample('H')
series2_hr = series2_hr.interpolate(method='time')
但还是没有运气。
所需的输出是 window 值为 1 的给定时间间隔(例如每小时)的百分比。换句话说,该小时的 window 的平均值(从 0 到 1).
示例:系列 2
datetime,window
2015-05-28 17:00:00,0.0
2015-05-28 17:55:28,1.0
2015-06-08 07:35:31,0.0
2015-06-08 08:04:30,1.0
2015-06-18 17:11:55,0.0
2015-06-18 18:11:52,1.0
2015-06-19 18:14:09,0.0
etc.
应该转换成series2_reg:
2015-05-28 17:00:00,0.916 (=(17:55 - 17:00)/60)
2015-05-28 18:00:00,1
2015-05-28 19:00:00,1
...
2015-06-08 07:00:00,0.583 (=(07:35 - 07:00)/60))
2015-06-08 08:00:00,0.06 (=(08:04 - 08:00)/60))
2015-06-08 09:00:00,1
2015-06-08 10:00:00,1
...
import io
import pandas as pd
data = io.StringIO('''\
datetime,window
2015-05-28 17:00:00,0.0
2015-05-28 17:55:28,1.0
2015-06-08 07:35:31,0.0
2015-06-08 08:04:30,1.0
2015-06-18 17:11:55,0.0
2015-06-18 18:11:52,1.0
2015-06-19 18:14:09,0.0
''')
s = pd.read_csv(data).set_index('datetime').squeeze()
s.index = pd.to_datetime(s.index)
首先以一分钟为间隔进行上采样,向前填充原始时间序列的条目。
upsampled = s.resample('min').ffill()
upsampled['2015-06-08 07:30':'2015-06-08 08:10']
# datetime
# 2015-06-08 07:30:00 1.0
# 2015-06-08 07:31:00 1.0
# 2015-06-08 07:32:00 1.0
# 2015-06-08 07:33:00 1.0
# 2015-06-08 07:34:00 1.0
# 2015-06-08 07:35:00 1.0
# 2015-06-08 07:36:00 0.0
# 2015-06-08 07:37:00 0.0
# 2015-06-08 07:38:00 0.0
# 2015-06-08 07:39:00 0.0
# 2015-06-08 07:40:00 0.0
# 2015-06-08 07:41:00 0.0
# 2015-06-08 07:42:00 0.0
# 2015-06-08 07:43:00 0.0
# 2015-06-08 07:44:00 0.0
# 2015-06-08 07:45:00 0.0
# 2015-06-08 07:46:00 0.0
# 2015-06-08 07:47:00 0.0
# 2015-06-08 07:48:00 0.0
# 2015-06-08 07:49:00 0.0
# 2015-06-08 07:50:00 0.0
# 2015-06-08 07:51:00 0.0
# 2015-06-08 07:52:00 0.0
# 2015-06-08 07:53:00 0.0
# 2015-06-08 07:54:00 0.0
# 2015-06-08 07:55:00 0.0
# 2015-06-08 07:56:00 0.0
# 2015-06-08 07:57:00 0.0
# 2015-06-08 07:58:00 0.0
# 2015-06-08 07:59:00 0.0
# 2015-06-08 08:00:00 0.0
# 2015-06-08 08:01:00 0.0
# 2015-06-08 08:02:00 0.0
# 2015-06-08 08:03:00 0.0
# 2015-06-08 08:04:00 0.0
# 2015-06-08 08:05:00 1.0
# 2015-06-08 08:06:00 1.0
# 2015-06-08 08:07:00 1.0
# 2015-06-08 08:08:00 1.0
# 2015-06-08 08:09:00 1.0
# 2015-06-08 08:10:00 1.0
# Freq: T, Name: window , dtype: float64
然后按小时重新采样,取每个区间的平均值。
result = upsampled.resample('H').mean()
result['2015-06-08 06:00':'2015-06-08 09:00']
# datetime
# 2015-06-08 06:00:00 1.000000
# 2015-06-08 07:00:00 0.600000
# 2015-06-08 08:00:00 0.916667
# 2015-06-08 09:00:00 1.000000
# Freq: H, Name: window , dtype: float64
请注意,上采样将事件的值分配给具有事件的一分钟。如果您的事件数据表示打开和关闭,这意味着 upsampled
中的每一分钟在该时间段结束时都具有 on/off 开关的状态。这就是为什么我的数字与你的不完全一致(另外,我相信你在 2015-06-08 08:00:00
处的计算有误)。
由于您的事件的粒度精确到秒,您可以按秒而不是按分钟进行上述上采样,从而获得更精确的每小时平均值 window
。
upsampled = s.resample('s').ffill()
result = upsampled.resample('H').mean()
result['2015-06-08 06:00':'2015-06-08 09:00']
# datetime
# 2015-06-08 06:00:00 1.000000
# 2015-06-08 07:00:00 0.591944
# 2015-06-08 08:00:00 0.925000
# 2015-06-08 09:00:00 1.000000
# Freq: H, Name: window , dtype: float64