使用 pandas 数据框计算累积 returns
Calculating cumulative returns with pandas dataframe
我有这个数据框
Poloniex_DOGE_BTC Poloniex_XMR_BTC Daily_rets perc_ret
172 0.006085 -0.000839 0.003309 0
173 0.006229 0.002111 0.005135 0
174 0.000000 -0.001651 0.004203 0
175 0.000000 0.007743 0.005313 0
176 0.000000 -0.001013 -0.003466 0
177 0.000000 -0.000550 0.000772 0
178 0.000000 -0.009864 0.001764 0
我正在尝试 运行 daily_rets perc_ret
但是我的代码只是复制了 daily_rets
中的值
df['perc_ret'] = ( df['Daily_rets'] + df['perc_ret'].shift(1) )
Poloniex_DOGE_BTC Poloniex_XMR_BTC Daily_rets perc_ret
172 0.006085 -0.000839 0.003309 NaN
173 0.006229 0.002111 0.005135 0.005135
174 0.000000 -0.001651 0.004203 0.004203
175 0.000000 0.007743 0.005313 0.005313
176 0.000000 -0.001013 -0.003466 -0.003466
177 0.000000 -0.000550 0.000772 0.000772
178 0.000000 -0.009864 0.001764 0.001764
如果性能很重要,请使用 numpy.cumprod
:
np.cumprod(1 + df['Daily_rets'].values) - 1
时间:
#7k rows
df = pd.concat([df] * 1000, ignore_index=True)
In [191]: %timeit np.cumprod(1 + df['Daily_rets'].values) - 1
41 µs ± 282 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [192]: %timeit (1 + df.Daily_rets).cumprod() - 1
554 µs ± 3.63 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
如果它们是每日简单的 returns 而你想要一个累积的 return,你肯定想要一个每日的复数吗?
df['perc_ret'] = (1 + df.Daily_rets).cumprod() - 1
# Or:
# df.Daily_rets.add(1).cumprod().sub(1)
>>> df
Poloniex_DOGE_BTC Poloniex_XMR_BTC Daily_rets perc_ret
172 0.006085 -0.000839 0.003309 0.003309
173 0.006229 0.002111 0.005135 0.008461
174 0.000000 -0.001651 0.004203 0.012700
175 0.000000 0.007743 0.005313 0.018080
176 0.000000 -0.001013 -0.003466 0.014551
177 0.000000 -0.000550 0.000772 0.015335
178 0.000000 -0.009864 0.001764 0.017126
如果它们是日志 returns,那么您可以只使用 cumsum
。
您不能简单地使用 cumsum
将它们全部相加
例如,如果你有数组 [1.1, 1.1],你应该有 2.21,而不是 2.2
import numpy as np
# daily return:
df['daily_return'] = df['close'].pct_change()
# calculate cumluative return
df['cumluative_return'] = np.exp(np.log1p(df['daily_return']).cumsum())
我有这个数据框
Poloniex_DOGE_BTC Poloniex_XMR_BTC Daily_rets perc_ret
172 0.006085 -0.000839 0.003309 0
173 0.006229 0.002111 0.005135 0
174 0.000000 -0.001651 0.004203 0
175 0.000000 0.007743 0.005313 0
176 0.000000 -0.001013 -0.003466 0
177 0.000000 -0.000550 0.000772 0
178 0.000000 -0.009864 0.001764 0
我正在尝试 运行 daily_rets perc_ret
但是我的代码只是复制了 daily_rets
中的值df['perc_ret'] = ( df['Daily_rets'] + df['perc_ret'].shift(1) )
Poloniex_DOGE_BTC Poloniex_XMR_BTC Daily_rets perc_ret
172 0.006085 -0.000839 0.003309 NaN
173 0.006229 0.002111 0.005135 0.005135
174 0.000000 -0.001651 0.004203 0.004203
175 0.000000 0.007743 0.005313 0.005313
176 0.000000 -0.001013 -0.003466 -0.003466
177 0.000000 -0.000550 0.000772 0.000772
178 0.000000 -0.009864 0.001764 0.001764
如果性能很重要,请使用 numpy.cumprod
:
np.cumprod(1 + df['Daily_rets'].values) - 1
时间:
#7k rows
df = pd.concat([df] * 1000, ignore_index=True)
In [191]: %timeit np.cumprod(1 + df['Daily_rets'].values) - 1
41 µs ± 282 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [192]: %timeit (1 + df.Daily_rets).cumprod() - 1
554 µs ± 3.63 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
如果它们是每日简单的 returns 而你想要一个累积的 return,你肯定想要一个每日的复数吗?
df['perc_ret'] = (1 + df.Daily_rets).cumprod() - 1
# Or:
# df.Daily_rets.add(1).cumprod().sub(1)
>>> df
Poloniex_DOGE_BTC Poloniex_XMR_BTC Daily_rets perc_ret
172 0.006085 -0.000839 0.003309 0.003309
173 0.006229 0.002111 0.005135 0.008461
174 0.000000 -0.001651 0.004203 0.012700
175 0.000000 0.007743 0.005313 0.018080
176 0.000000 -0.001013 -0.003466 0.014551
177 0.000000 -0.000550 0.000772 0.015335
178 0.000000 -0.009864 0.001764 0.017126
如果它们是日志 returns,那么您可以只使用 cumsum
。
您不能简单地使用 cumsum
将它们全部相加例如,如果你有数组 [1.1, 1.1],你应该有 2.21,而不是 2.2
import numpy as np
# daily return:
df['daily_return'] = df['close'].pct_change()
# calculate cumluative return
df['cumluative_return'] = np.exp(np.log1p(df['daily_return']).cumsum())