Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 数据帧中的对数返回_Python_Pandas - Fatal编程技术网

Python 数据帧中的对数返回

Python 数据帧中的对数返回,python,pandas,Python,Pandas,Python pandas有一个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 i

Python pandas有一个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

下面是使用
.shift()
计算日志返回的一种方法。结果与
pct\u change()
计算的总回报率相似,但不相同。你能上传你的样本数据副本(dropbox共享链接)来重现你看到的不一致吗

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();

日志返回值是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都提供了前一个日期的值。

我在pct_change()和log_ret中得到了许多完全相同的值,还有一些值略有不同。这是意料之中的吗?@AmanArora是的,这是意料之中的行为。当你的总回报率很小,比如说低于1%时,对数回报率和总回报率非常接近。它可以通过0左右的二阶泰勒展开得到数学上的证明。@AmanArora顺便说一句,对数收益率有一个理想的特性,即它随时间的推移是可加的(但在不同的资产上不是可加的),而当你计算加权平均投资组合收益率时,总收益率是最合适的(这是对不同资产的加法,但不是对时间的加法)。这将计算两次日志,而不是使用.diff()@poulter7.dif()提供两行之间的绝对变化。还要注意,
np.log(df.price)-np.log(df.price.shift(1))
相当于
np.log(df.price/df.price.shift(1))
(一次日志操作)这很有趣,这里有两种方法,
np.log(1+s.pct_change())
np.log(s/s.shift(1))
,这两种方法是等效的,一旦序列跨入负区域,日志返回的开始再次有意义。或者
np.log.diff()
(np.log(s)-np.log(s.shift(1))
,它显式地删除负返回。也许您可以使用np.log1p:df['log\u return']=np.log1p(df.pct\u change)这在数学上肯定是不正确的“日志返回只是1的自然日志加上算术返回。”它可以工作,但显示PyLint消息“ndarray”的实例没有'diff'成员”这突出显示了numpy API中的一个更改。在最新版本的numpy中,数组本身没有.diff()可用。相反,np.diff是首选方法。更新了答案以反映这一点。