我将尝试解释我目前遇到的有关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
天重新评估(从零开始)?
希望它足够清楚,
谢谢, Ñ
答案 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),它总是得到正确的滚动总和,从前一个日期开始,初始值为零