【问题标题】:Rolling Mean with Time Offset Pandas带有时间偏移 Pandas 的滚动平均值
【发布时间】:2019-07-06 17:12:11
【问题描述】:

我在 pandas 中有一组时间戳和值。时间戳之间的间隔在大约一年的总时间跨度内约为 12 秒,但有时会丢失点(即时间序列是不规则的,所以我不能使用固定的窗口大小)。

我想计算 1 分钟间隔内的值的滚动平均值,但我没有得到我预期的行为。我发现了一个类似的问题here,但那是使用 sum 和 pre-pandas 0.19.0。我正在使用 Pandas 0.23.4。

样本数据

Time, X
2018-02-02 21:27:00,    75.4356
2018-02-02 21:27:12,    78.29821
2018-02-02 21:27:24,    73.098345
2018-02-02 21:27:36,    78.3331
2018-02-02 21:28:00,    79.111

请注意,2018-02-02 21:27:48 已丢失。

对于滚动求和,我可以只用 0 填充缺失值,但对于平均值,我不希望缺失点被计为真实数据点(例如,我希望窗口为 sum(data points在给定的区间内)/区间内的数据点数)。

我想在不同的时间段(即 1 分钟、5 分钟、15 分钟、1 小时等)执行此操作。

最接近实际值的方法是:

代码

df['rolling_avg']=df.rolling('1T',on='Time').X.mean()

我的理解是 1 分钟的滚动平均值。

但是,我不确定如何解释输出。我本来预计前 1+1 分钟会出现 NaN,因为没有什么可以作为滚动平均值的基础,但我有值。

输出

    Time                X         rolling_avg
0   2018-02-02 21:27:00 75.4356   75.435600
1   2018-02-02 21:27:12 78.29821  76.866905
2   2018-02-02 21:27:24 73.098345 75.610718
3   2018-02-02 21:27:36 78.3331   76.291314
4   2018-02-02 21:28:00 79.111    77.210164

基本上,在此输出中,df[1].rolling_avg(Value[0]+Value[1])/2,尽管间隔是 12 秒,而不是 1 分钟。

有没有办法做我想做的事情,还是我需要编写一个 for 循环来手动执行此操作?

【问题讨论】:

  • 试试这个... df['rolling_avg']=df.rolling('60s').X.mean()
  • @run-out 这给了ValueError: window must be an integer
  • 在下面我的回答中,我想知道您的日期时间格式是否正确。如果是字符串就不行。
  • 输出看起来不一致吗?您正在寻找 1 分钟间隔的平均值..

标签: python pandas dataframe moving-average rolling-average


【解决方案1】:

我认为问题可能出在您的数据中。然后也许我没有解决问题。使用您的数据时我遇到了同样的错误,但是当我尝试这个时它起作用了。

import  pandas as pd
import numpy as np
import datetime

time = pd.date_range(start='1/1/2018', end='1/02/2018', freq='12s')
time

DatetimeIndex(['2018-01-01 00:00:00', '2018-01-01 00:00:12',
               '2018-01-01 00:00:24', '2018-01-01 00:00:36',
               '2018-01-01 00:00:48', '2018-01-01 00:01:00',
               '2018-01-01 00:01:12', '2018-01-01 00:01:24',
               '2018-01-01 00:01:36', '2018-01-01 00:01:48',
               ...
               '2018-01-01 23:58:12', '2018-01-01 23:58:24',
               '2018-01-01 23:58:36', '2018-01-01 23:58:48',
               '2018-01-01 23:59:00', '2018-01-01 23:59:12',
               '2018-01-01 23:59:24', '2018-01-01 23:59:36',
               '2018-01-01 23:59:48', '2018-01-02 00:00:00'],
              dtype='datetime64[ns]', length=7201, freq='12S')

B = np.random.randint(0, 9, 7201)

df = pd.DataFrame(B, time)
df['rolling_avg']=df.rolling('60s', min_periods=3).mean()
df.head(20)

    0                rolling_avg
2018-01-01 00:00:00 5   NaN
2018-01-01 00:00:12 0   NaN
2018-01-01 00:00:24 1   2.0
2018-01-01 00:00:36 0   1.5
2018-01-01 00:00:48 6   2.4
2018-01-01 00:01:00 7   2.8
2018-01-01 00:01:12 6   4.0
2018-01-01 00:01:24 3   4.4
2018-01-01 00:01:36 7   5.8
2018-01-01 00:01:48 6   5.8
2018-01-01 00:02:00 2   4.8
2018-01-01 00:02:12 6   4.8
2018-01-01 00:02:24 1   4.4
2018-01-01 00:02:36 0   3.0
2018-01-01 00:02:48 8   3.4
2018-01-01 00:03:00 2   3.4
2018-01-01 00:03:12 5   3.2
2018-01-01 00:03:24 8   4.6
2018-01-01 00:03:36 4   5.4
2018-01-01 00:03:48 1   4.0

【讨论】:

    【解决方案2】:

    你说:但是,我不确定如何解释输出。我本来预计前 1+1 分钟会出现 NaN,因为没有任何东西可以作为滚动平均值的基础,但我有值。

    .rolling() 方法会考虑索引在 1 分钟间隔内的所有值。区间左开右闭(by default, but you can change this; use the optional parameter closed)。它的右端是当前索引 (you can change this,too; use the optional parameter center)。
    在您的情况下,第一个这样的间隔是]2018-02-02 21:26:002018-02-02 21:27:00],它只包含索引2018-02-02 21:27:00。因此,平均值只计算一个值。

    因此,我实际上认为这正是您想要的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-12
      • 2021-11-11
      • 2018-05-08
      • 1970-01-01
      • 1970-01-01
      • 2019-06-16
      • 1970-01-01
      相关资源
      最近更新 更多