【问题标题】:1 Year Rolling mean pandas on column date列日期的 1 年滚动平均熊猫
【发布时间】:2018-08-29 11:52:19
【问题描述】:

我想计算此 Dataframe test 中每一行的 1 年滚动平均值:

index   id      date        variation
2313    7034    2018-03-14  4.139148e-06
2314    7034    2018-03-13  4.953194e-07
2315    7034    2018-03-12  2.854749e-06
2316    7034    2018-03-09  3.907458e-06
2317    7034    2018-03-08  1.662412e-06
2318    7034    2018-03-07  1.346433e-06
2319    7034    2018-03-06  8.731700e-06
2320    7034    2018-03-05  7.145597e-06
2321    7034    2018-03-02  4.893283e-06
...

例如,我需要计算:

  • id 7034 在 2018-03-14 和 2017-08-14 之间的平均变化
  • id 7034 在 2018-03-13 和 2017-08-13 之间的平均变化
  • 等

我试过了:

test.groupby(['id','date'])['variation'].rolling(window=1,freq='Y',on='date').mean()

但我收到了错误消息:

ValueError: invalid on specified as date, must be a column (if DataFrame) or None

在这种情况下如何使用 pandas rolling() 函数?


[编辑 1] [感谢 Sacul]

我测试过:

df['date'] = pd.to_datetime(df['date'])

df.set_index('date').groupby('id').rolling(window=1, freq='Y').mean()['variation']

但是freq='Y' 不起作用(我得到:ValueError: Invalid frequency: Y)然后我使用了window = 365, freq = 'D'。

但还有另一个问题:因为每个组合 id-date 永远不会有 365 个连续日期,因此结果始终为空。即使缺少日期,我也想忽略它们并考虑当前日期和(当前日期 - 365)之间的所有日期来计算滚动平均值。例如,假设我有:

index   id      date        variation
2313    7034    2018-03-14  4.139148e-06
2314    7034    2018-03-13  4.953194e-07
2315    7034    2017-03-13  2.854749e-06

那么,

  • 对于 7034 2018-03-14:我想计算 MEAN(4.139148e-06,4.953194e-07, 2.854749e-06)
  • 对于 7034 2018-03-13:我还想计算 MEAN(4.139148e-06,4.953194e-07, 2.854749e-06)

我该怎么做?


[编辑 2]

最后我使用下面的公式通过忽略缺失值来计算 1 年的滚动中位数、平均值和标准差:

pd.rolling_median(df.set_index('date').groupby('id')['variation'],window=365, freq='D',min_periods=1)

pd.rolling_mean(df.set_index('date').groupby('id')['variation'],window=365, freq='D',min_periods=1)

pd.rolling_std(df.set_index('date').groupby('id')['variation'],window=365, freq='D',min_periods=1)

【问题讨论】:

  • 格式正确,显示尝试,明确给出错误。欢迎使用 stackoverflow!

标签: python pandas rolling-computation rolling-average


【解决方案1】:

我相信这应该适合你:

# First make sure that `date` is a datetime object:

df['date'] = pd.to_datetime(df['date'])

df.set_index('date').groupby('id').rolling(window=1, freq='A').mean()['variation']

当date 是索引时,使用带有日期时间的pd.DataFrame.rolling 效果很好,这就是我使用df.set_index('date') 的原因(可以在documentation's examples 之一中看到)

我无法真正测试它是否适用于您的示例数据框的年度平均值,因为只有一年且只有一个 ID,但它应该可以工作。

可以说是更好的解决方案:

[编辑] 正如 Mihai-Andrei Dinculescu 所指出的,freq 现在已被弃用。这是一种替代方法(可能更面向未来)来做您正在寻找的事情:

df.set_index('date').groupby('id')['variation'].resample('A').mean()

您可以查看resample 文档以了解有关其工作原理的更多详细信息,以及查看this link 有关频率参数的更多详细信息。

【讨论】:

  • ValueError: Invalid frequency: Y
  • 这可能与freq 已被弃用有关。 pandas.pydata.org/pandas-docs/stable/generated/…
  • 这很奇怪,它对我有用。基于this link,当您尝试使用频率'A' 时它是否有效?应该做同样的事情。
  • A 工作正常。你用的是什么版本的熊猫?
  • 0.21.1。很高兴它有效。似乎在旧版本中,'A' 是唯一可接受的年终频率别名 (as seen in this answer),但当前的 documentation 包括 'A' 和 'Y' 作为别名。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 1970-01-01
  • 2023-01-31
  • 2019-07-27
相关资源
最近更新 更多