【问题标题】:Pandas time series decomposition based on leap year [duplicate]基于闰年的熊猫时间序列分解[重复]
【发布时间】:2018-11-07 06:22:04
【问题描述】:

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

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)

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

def decide(row):
    if (row.name - 59).is_leap_year:
        return row[1]
    else:
        return row[0]

df['yearly_diff'] = df[['diff_365', 'diff_366']].apply(decide, axis=1)

解释:函数 decide 将 DataFrame 中的一行作为参数,该行由列 diff_365diff_366(连同日期时间索引)。表达式 row.name 返回行的日期并假设时间序列具有每日频率 (freq = 'D'),减去 59 天,即从 1 月 1 日到 2 月 28 日这几天。根据结果​​日期是否为闰年的某一天,返回 diff_366 列中的值,否则返回 diff_365 列中的值。

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

【问题讨论】:

    标签: python pandas time-series decomposition


    【解决方案1】:

    您可能无需担心明确处理闰年。构造DatetimeIndex时,可以指定startend参数。根据docs

    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)
    

    说明

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-21
      • 2017-11-30
      • 1970-01-01
      • 2017-06-07
      • 2016-08-14
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多