我想使用开始日期,结束日期和“粒度”重新采样日期时间索引数据帧
说我有这个数据帧:
value
00:00, 01/05/2017 2
12:00, 01/05/2017 4
00:00, 02/05/2017 6
12:00, 02/05/2017 8
00:00, 03/05/2017 10
12:00, 03/05/2017 12
我想重新采样它从2017年5月1日06:00到
18:00 02/05/2017,“粒度”为12小时(为简单起见,这与原始版本相同,但并非必须如此).我想要的结果是:
value
06:00, 01/05/2017 3
18:00, 01/05/2017 5
06:00, 02/05/2017 7
18:00, 02/05/2017 9
请注意,这些值是它们重叠的值的平均值(例如3 =平均值(2,4))
我不确定该怎么做.
我的第一次尝试是:
def resample(df: DataFrame, start: datetime, end: datetime, granularity: timedelta) -> DataFrame:
result = df.resample(granularity).mean()
result = result[result.index <= end]
result = result[result.index >= start]
return result
这会适当地修剪数据框并确保正确的粒度,但不会将结果与开始日期对齐,因此结果为:
value
12:00, 01/05/2017 4
00:00, 02/05/2017 6
12:00, 02/05/2017 8
我的第二次尝试使用base参数来移动数据:
def resample(df: DataFrame, start: datetime, end: datetime, desired_granularity: timedelta) -> DataFrame:
data_before_start = df[df.index <= start]
# Get the last index value before our start date
last_date_before_start = data_before_start.last_valid_index()
current_granularity_secs = seconds_between_measurements(df)
rule = str(int(desired_granularity.total_seconds())) + 'S'
base = current_granularity_secs - (start - last_date_before_start).total_seconds()
result = df.resample(rule, base=base).mean()
result = result[result.index < end]
result = result[result.index >= start]
return result
这给了我:
value
06:00, 01/05/2017 4
18:00, 01/05/2017 6
06:00, 02/05/2017 8
18:00, 02/05/2017 10
这具有正确的指数,但是值从下一次测量回填,而不是从之前和之后的测量值平均.
有没有人对如何实现我想要的东西有任何想法?
在此先感谢您的帮助,如果我遗漏了任何重要细节,请告诉我:)
编辑:
如果获得平均值是使得这非常棘手的一点,我可以在给定时间之前使用该值,类似于pad().我现在的’最佳’解决方案给了我后面的价值,比如回填()
解决方法:
首先将end_start和end_date列定义为datetime.
然后,您可以使用.resample两次:
>在带正向填充的df.start_date上
>在带有向后填充的df.end_date上
然后:
>将行保持在start_date<结束日期
>连接
>在每一行上应用一个函数来更新start_date和end_date:
这里的代码:
df[["start_date","end_date"]] = df[["start_date","end_date"]].astype(np.datetime64)
df1 = df.set_index("start_date").resample(freq).pad().reset_index()
df2 = df.set_index("end_date").resample(freq).bfill().reset_index()
df3 = pd.concat([df1, df2], ignore_index=True)
def function(x, df1):
if x.name < df1.shape[0]:
x.end_date = x.start_date + pd.timedelta(freq)
else:
x.start_date = x.end_date - pd.timedelta(freq)
return x
df3[ df3.start_date < df3.end_date ].apply(lambda x: function(x, df1), axis=1)
Pandas documentation say that it should be possible directly to resample
df.resample(freq, on='start_date')
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。