熊猫滚动总和,变化长度

时间:2015-01-12 15:21:25

标签: python pandas dataframe

我将尝试解释我目前遇到的有关Python中DataFrames累积总和的问题,希望你能掌握它!

给定一个pandas DataFrame df,其中包含returns列:

              returns
Date                                                          
2014-12-10    0.0000
2014-12-11    0.0200
2014-12-12    0.0500
2014-12-15    -0.0200
2014-12-16    0.0000

在此DataFrame上应用累积总和很简单,只需使用例如df.cumsum()。但是,每隔X天(或数据点)说是否可以应用累积金额,只产生最后Y天的累积总和(数据点)。

澄清:根据上述每日数据,我如何得到过去Y天的累积总和,每X天重新评估(从零开始)?

希望它足够清楚,

谢谢, Ñ

4 个答案:

答案 0 :(得分:2)

"每隔X天"和"每个X数据点"非常不同;以下假设你真的是第一个,因为你更频繁地提到它。

如果索引是DatetimeIndex,您可以resample到每日频率,选择rolling_sum,然后只选择原始日期:

>>> pd.rolling_sum(df.resample("1d"), 2, min_periods=1).loc[df.index]
            returns
Date               
2014-12-10     0.00
2014-12-11     0.02
2014-12-12     0.07
2014-12-15    -0.02
2014-12-16    -0.02

或,一步一步:

>>> df.resample("1d")
            returns
Date               
2014-12-10     0.00
2014-12-11     0.02
2014-12-12     0.05
2014-12-13      NaN
2014-12-14      NaN
2014-12-15    -0.02
2014-12-16     0.00
>>> pd.rolling_sum(df.resample("1d"), 2, min_periods=1)
            returns
Date               
2014-12-10     0.00
2014-12-11     0.02
2014-12-12     0.07
2014-12-13     0.05
2014-12-14      NaN
2014-12-15    -0.02
2014-12-16    -0.02

答案 1 :(得分:0)

我不确定是否有内置方法,但编写方法似乎并不困难。 例如,这里有一个熊猫系列。

def cum(df, interval):
    all = []
    quotient = len(df)//interval
    intervals = range(quotient)
    for i in intervals:
        all.append(df[0:(i+1)*interval].sum())
    return pd.Series(all)
>>>s1 = pd.Series(range(20))
>>>print(cum(s1, 4))
0     6
1    28
2    66
3   120
4   190
dtype: int64

答案 2 :(得分:0)

我这样做的方法是使用辅助列。它有点笨拙,但应该有效:

numgroups = int(len(df)/(x-1))
df['groupby'] = sorted(list(range(numgroups))*x)[:len(df)]
df['mask'] = (([0]*(x-y)+[1]*(y))*numgroups)[:len(df)]
df['masked'] = df.returns*df['mask']
df.groupby('groupby').masked.cumsum()

答案 3 :(得分:0)

感谢@DSM,我设法提出了他的解决方案的变体,实际上我正在寻找的东西:

import numpy as np
import pandas as pd

df.resample("1w"), how={'A': np.sum})

为下面的例子提供我想要的东西:

rng = range(1,29)
dates = pd.date_range('1/1/2000', periods=len(rng))
r = pd.DataFrame(rng, index=dates, columns=['A'])
r2 = r.resample("1w", how={'A': np.sum})

输出:

>> print r
             A
2000-01-01   1
2000-01-02   2
2000-01-03   3
2000-01-04   4
2000-01-05   5
2000-01-06   6
2000-01-07   7
2000-01-08   8
2000-01-09   9
2000-01-10  10
2000-01-11  11
...
2000-01-25  25
2000-01-26  26
2000-01-27  27
2000-01-28  28

>> print r2
              A
2000-01-02    3
2000-01-09   42
2000-01-16   91
2000-01-23  140
2000-01-30  130

即使它在这种情况下没有开始“一周”(在第一种情况下导致总和为3),它总是得到正确的滚动总和,从前一个日期开始,初始值为零