熊猫数据框架中的对数返回

Python 熊猫有一个 pct _ change 函数,我用它来计算数据框架中股票价格的收益:

ndf['Return']= ndf['TypicalPrice'].pct_change()

我使用下面的代码来获得对数返回值,但它给出的值与 pct.change ()函数完全相同:

ndf['retlog']=np.log(ndf['TypicalPrice'].astype('float64')/ndf['TypicalPrice'].astype('float64').shift(1))
#np is for numpy
241695 次浏览

下面是使用 .shift()计算日志返回的一种方法。结果与 pct_change()计算的总收益相似但不相同。你能上传一份你的样本数据(下拉框共享链接)来重现你看到的不一致吗?

import pandas as pd
import numpy as np


np.random.seed(0)
df = pd.DataFrame(100 + np.random.randn(100).cumsum(), columns=['price'])
df['pct_change'] = df.price.pct_change()
df['log_ret'] = np.log(df.price) - np.log(df.price.shift(1))


Out[56]:
price  pct_change  log_ret
0   101.7641         NaN      NaN
1   102.1642      0.0039   0.0039
2   103.1429      0.0096   0.0095
3   105.3838      0.0217   0.0215
4   107.2514      0.0177   0.0176
5   106.2741     -0.0091  -0.0092
6   107.2242      0.0089   0.0089
7   107.0729     -0.0014  -0.0014
..       ...         ...      ...
92  101.6160      0.0021   0.0021
93  102.5926      0.0096   0.0096
94  102.9490      0.0035   0.0035
95  103.6555      0.0069   0.0068
96  103.6660      0.0001   0.0001
97  105.4519      0.0172   0.0171
98  105.5788      0.0012   0.0012
99  105.9808      0.0038   0.0038


[100 rows x 3 columns]

结果可能与 看起来相似,但这仅仅是因为 对数的泰勒展开式。由于 Log (1 + x) ~ x,结果可能是相似的。

但是,

我使用以下代码来获得对数返回值,但它给出的值与 pct.change ()函数完全相同。

并不完全正确。

import pandas as pd


df = pd.DataFrame({'p': range(10)})


df['pct_change'] = df.pct_change()
df['log_stuff'] = \
np.log(df['p'].astype('float64')/df['p'].astype('float64').shift(1))
df[['pct_change', 'log_stuff']].plot();

enter image description here

日志返回值只是自然的1加上算术返回值的日志。那么这个怎么样呢?

df['pct_change'] = df.price.pct_change()
df['log_return'] = np.log(1 + df.pct_change)

更简洁的是,利用 希米克斯的建议:

df['log_return'] = np.log1p(df.price.pct_change())

单行,只计算一次日志。 首先转换为日志空间,然后采用1周期差异。

    np.diff(np.log(df.price))

在 numpy 的早期版本中:

    np.log(df.price)).diff()

@ poulter7: 我不能评论其他的答案,所以我把它作为新的答案: 小心

np.log(df.price).diff()

因为负利率等可能成为负数的指数和风险因素都会失效。在这种情况下

np.log(df.price/df.price.shift(1)).dropna()

根据我的经验,一般较安全的方法。它也只计算对数一次。

使用 + 1还是 -1取决于时间序列的顺序。降序使用 -1,升序使用 + 1——在这两种情况下,shift 都提供了前一个日期的值。