熊猫:累积回归功能

时间:2016-11-25 19:23:27

标签: python pandas dataframe finance

我有一个如下数据框:

  Index      Return
2008-11-21   0.153419
2008-11-24   0.037421
2008-11-25   0.077500

计算最后一行所有列的累积回报的最佳方法是什么?

以下是预期结果:

  Index      Return
2008-11-21   0.153419
2008-11-24   0.037421
2008-11-25   0.077500
Cumulative   0.289316

累积回报的计算方法如下:

cumulative = (1 + return1) * (1 + return2) * (1 + return3) - 1 

在熊猫中执行此操作的最佳方式是什么?

5 个答案:

答案 0 :(得分:10)

有一个pandas cumprod()方法。这适用于每一列。

df.ix["Cumulative"] = ((df+1).cumprod()-1).iloc[-1]

这比大型数据集上的其他解决方案快2倍:

In[106]: %timeit df.ix["Cumulative"] = ((df+1).cumprod()-1).iloc[-1]
10 loops, best of 3: 18.4 ms per loop
In[107]: %timeit df.ix['Cummulative'] = df.apply(lambda x: (x+1).prod()-1)
10 loops, best of 3: 32.9 ms per loop
In[110]: %timeit df.append(df.iloc[:,1:].apply(lambda col: (col + 1).prod() - 1), ignore_index=True)
10 loops, best of 3: 37.1 ms per loop
In[113]: %timeit df.append(df.apply(lambda col: prod([(1+c) for c in col]) - 1), ignore_index=True)
1 loop, best of 3: 262 ms per loop

我建议从不使用apply如果你能找到一个内置方法,因为apply循环遍历数据帧,这使得它变慢。 Bult-in方法非常高效,通常情况下,使用apply无法让你获得更快的速度。

答案 1 :(得分:4)

另一种解决方案:

df.ix["Cumulative"] = (df['Return']+1).prod() - 1

这将向df['Return']列添加1,将所有行相乘,然后从结果中减去1。这将导致一个简单的浮点值。然后将结果放在索引" Cumulative"。由于该指数尚不存在,it will be appended to the end of the DataFrame

               Return
2008-11-21   0.153419
2008-11-25   0.077500
2008-11-24   0.037421
Cummulative  0.289316

如果要在多个列中应用此功能:

df.ix['Cummulative'] = df.apply(lambda x: (x+1).prod()-1)

这将输出以下内容(我做了第二列名为" Return2"这是&#34的副本;返回"):

               Return   Return2
2008-11-21   0.153419  0.153419
2008-11-25   0.077500  0.077500
2008-11-24   0.037421  0.037421
Cummulative  0.289316  0.289316

答案 2 :(得分:2)

使用pandas,您可以使用prod()方法:

df.append(df.iloc[:,1:].apply(lambda col: (col + 1).prod() - 1), ignore_index=True)

#        Index    Return
#0  2008-11-21  0.153419
#1  2008-11-24  0.037421
#2  2008-11-25  0.077500
#3         NaN  0.289316

或者@Randy C评论说,这可以进一步简化为:

df.append((df.iloc[:,1:] + 1).prod() - 1, ignore_index=True)

答案 3 :(得分:1)

一种选择是使用reduce,但其他人可能会提出更快的矢量化方法:

In [10]: pd.read_clipboard()
Out[10]:
        Index    Return
0  2008-11-21  0.153419
1  2008-11-24  0.037421
2  2008-11-25  0.077500

In [11]: reduce(lambda x, y: (1+x)*(1+y)-1, _10['Return'])
Out[11]: 0.28931612705992227

请注意,在Python 3中,reducefunctools库的一部分,尽管它是Python 2的内置函数。

答案 4 :(得分:1)

这是我的:

from numpy import prod
df.append(df.apply(lambda col: prod([(1+c) for c in col]) - 1), ignore_index=True)