索引&将func应用于带有DateOffset的pandas DataFrame

时间:2017-07-21 14:40:46

标签: python python-3.x pandas datetime time-series

以正常分布的术语获取以下DataFrame,其中有一个很小的漂移:

np.random.seed(123)
df = pd.DataFrame(np.random.randn(60,3) / 100 + 0.005, 
                  index=pd.date_range(end='2017-06-30', periods=60, freq='M'))

并定义将应用于列的函数rollup

def rollup(r):
    return r.add(1.).prod() -1.

例如,调用整个df会给我:

print(rollup(df))
0    0.17411
1    0.35658
2    0.24944
dtype: float64

但我想做的是从df索引中的最后日期取一个日期偏移量,并将rollup应用于该子帧。我正确地做到了这一点,如下所示,但是想知道是否有一种替代方法使用少量的线。

from pandas.tseries.offsets import DateOffset
end = df.index[-1]

start = end - DateOffset(years=2)    
print(df[start:end].apply(rollup))
0    0.07905
1    0.18037
2    0.09656
dtype: float64

# example 2
start = end - DateOffset(months=6)    
print(df[start:end].apply(rollup))
0    0.01656
1    0.06585
2    0.01463
dtype: float64

最后一段代码可以压缩吗? Time Series / Date functionality中是否有其他方法不要求我指定end,应用DateOffset,然后在两者之间编制df

如果这是最简单的方法,需要最少的代码,那对我来说就是答案。

1 个答案:

答案 0 :(得分:1)

首先,我要说你的代码非常简洁。我会做出这样的观察和建议:

您的索引的创建频率为'M',并且会延伸到每个人Timestamp。这意味着那些对象现在知道如何处理整数的加法和减法。 pandas所做的假设整数采用频率表示的偏移量。

示例

df.index[-1]

Timestamp('2017-06-30 00:00:00', freq='M')

并且

df.index[-1] - 2

Timestamp('2017-04-30 00:00:00', freq='M')

我们可以用它来实现你的目标

rollup(df[df.index[-1] - 2:])  # last 2 months

rollup(df[df.index[-1] - 24:])  # last 2 years

额外信用

此数学也适用于整个索引。

df.index + 2

为每个索引值添加两个月。