繁体   English   中英

熊猫-使用指定的开始日期,结束日期和粒度重新采样数据框

[英]pandas - Resample a dataframe using a specified start date, end date and granularity

我想使用开始日期,结束日期和“粒度”对日期时间索引的数据帧进行重新采样

说我有这个数据框:

                   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

我想对其进行重新采样,使其从06:00, 01/05/2017
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 = mean(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()。 我目前的“最佳”解决方案为我带来了价值,例如backfill()

首先将您的end_start和end_date列定义为datetime。 然后,您可以使用.resample两次:

  • 在df.start_date上进行向前填充
  • 在df.end_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)

熊猫文件说应该应该可以直接重新采样

df.resample(freq, on='start_date')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM