基于闰年的熊猫时间序列分解

时间:2018-05-28 16:04:21

标签: python pandas time-series decomposition

我有一个大熊猫时间序列(称为 df ),它有一列(名称为 data ),其中包含5年时间内每日频率的数据。以下代码生成一些随机数据:

(setq split-height-threshold 5)
(setq split-width-threshold 5)

我想进行一个简单的年度趋势分解,每天我减去一年前的价值。另外,我想参加减法中的闰年。有没有优雅的方法呢?我这样做的方法是在365天和366天执行差异并将它们分配给新列。

import pandas as pd
import numpy as np


df_index = pd.date_range('01-01-2012', periods=5 * 365 + 2, freq='D')
df = pd.DataFrame({'data': np.random.rand(len(df_index))}, index=df_index)

之后,我根据去年的相同日期是365天还是366天前,为每一行选择一个正确的值。

df['diff_365'] = df['data'].diff(365)
df['diff_366'] = df['data'].diff(366)

解释:函数决定将DataFrame中的行作为参数从 diff_365 diff_366 (以及DatetimeIndex)。表达式 row.name 返回行的日期,并假设时间序列具有每日频率( freq =' D' ),减去59天这是从1月1日到2月28日的天数。根据生成的日期是否是闰年的一天,将返回 diff_366 列中的值,否则返回 diff_365 列中的值。

这需要8行,并且感觉可以在一行或两行中执行减法。我尝试将类似的函数直接应用于 data 列(通过 apply 并采用默认参数 axis = 0 )。但在这种情况下,我不能考虑我的DatetimeIndex。有没有更好的执行减法?

1 个答案:

答案 0 :(得分:0)

您可能不必担心明确处理闰年。构建DatetimeIndex时,您可以指定startend参数。根据{{​​3}}:

  

startendperiodsfreq四个参数中,正好三个   必须指定。

以下是如何重构逻辑的示例:

df_index = pd.date_range(start='01-01-2012', end='12-31-2016', freq='D')

df = pd.DataFrame({'data': np.random.rand(len(df_index))}, index=df_index)

df['yearly_diff'] = df['data'] - (df_index - pd.DateOffset(years=1)).map(df['data'].get)

<强>解释

  • 我们通过提供DatetimeIndexstartend参数来构建freq对象。
  • 减去pd.DateOffset(years=1)
  • ,从索引中减去1年
  • 使用pd.Series.map将这些1年代日期映射到data
  • 从原始data系列中减去结果系列。