我有一个大熊猫时间序列(称为 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。有没有更好的执行减法?
答案 0 :(得分:0)
您可能不必担心明确处理闰年。构建DatetimeIndex
时,您可以指定start
和end
参数。根据{{3}}:
在
start
,end
,periods
和freq
四个参数中,正好三个 必须指定。
以下是如何重构逻辑的示例:
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)
<强>解释强>
DatetimeIndex
,start
和end
参数来构建freq
对象。pd.DateOffset(years=1)
pd.Series.map
将这些1年代日期映射到data
。data
系列中减去结果系列。