gpt4 book ai didi

python - pandas - 使用指定的开始日期、结束日期和粒度对数据框重新采样

转载 作者:太空宇宙 更新时间:2023-11-03 11:43:56 26 4
gpt4 key购买 nike

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

假设我有这个数据框:

                   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()。我目前的“最佳”解决方案给了我之后的值(value),比如 backfill()

最佳答案

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

  • 在 df.start_date 上进行前向填充
  • 在 df.end_date 上向后填充

然后:

  • 保留 start_date < 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)

Pandas documentation say that it should be possible directly to resample

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

关于python - pandas - 使用指定的开始日期、结束日期和粒度对数据框重新采样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43806497/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com