Pandas:累计return函数
Pandas: Cumulative return function
我有一个如下所示的数据框:
Index Return
2008-11-21 0.153419
2008-11-24 0.037421
2008-11-25 0.077500
计算最后一行所有列的累积 return 的最佳方法是什么?
以下是预期结果:
Index Return
2008-11-21 0.153419
2008-11-24 0.037421
2008-11-25 0.077500
Cumulative 0.289316
其中累计return计算如下:
cumulative = (1 + return1) * (1 + return2) * (1 + return3) - 1
在 pandas 中执行此操作的最佳方法是什么?
一种选择是只使用 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 中,reduce
是 functools
库的一部分,尽管它是 Python 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)
这是我的:
from numpy import prod
df.append(df.apply(lambda col: prod([(1+c) for c in col]) - 1), ignore_index=True)
另一个解决方案:
df.ix["Cumulative"] = (df['Return']+1).prod() - 1
这会将 1 添加到 df['Return']
列,将所有行相乘,然后从结果中减去 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" 的第二列,它是 "Return" 的副本):
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
有一个 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 会遍历数据帧,这会使其变慢。内置方法非常高效,通常您无法使用 apply 比它们更快。
我有一个如下所示的数据框:
Index Return
2008-11-21 0.153419
2008-11-24 0.037421
2008-11-25 0.077500
计算最后一行所有列的累积 return 的最佳方法是什么?
以下是预期结果:
Index Return
2008-11-21 0.153419
2008-11-24 0.037421
2008-11-25 0.077500
Cumulative 0.289316
其中累计return计算如下:
cumulative = (1 + return1) * (1 + return2) * (1 + return3) - 1
在 pandas 中执行此操作的最佳方法是什么?
一种选择是只使用 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 中,reduce
是 functools
库的一部分,尽管它是 Python 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)
这是我的:
from numpy import prod
df.append(df.apply(lambda col: prod([(1+c) for c in col]) - 1), ignore_index=True)
另一个解决方案:
df.ix["Cumulative"] = (df['Return']+1).prod() - 1
这会将 1 添加到 df['Return']
列,将所有行相乘,然后从结果中减去 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" 的第二列,它是 "Return" 的副本):
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
有一个 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 会遍历数据帧,这会使其变慢。内置方法非常高效,通常您无法使用 apply 比它们更快。