我有一个包含月度财务数据的数据框:
In [89]: vfiax_monthly.head()
Out[89]:
year month day d open close high low volume aclose
2003-01-31 2003 1 31 731246 64.95 64.95 64.95 64.95 0 64.95
2003-02-28 2003 2 28 731274 63.98 63.98 63.98 63.98 0 63.98
2003-03-31 2003 3 31 731305 64.59 64.59 64.59 64.59 0 64.59
2003-04-30 2003 4 30 731335 69.93 69.93 69.93 69.93 0 69.93
2003-05-30 2003 5 30 731365 73.61 73.61 73.61 73.61 0 73.61
我正在尝试计算这样的回报:
In [90]: returns = (vfiax_monthly.open[1:] - vfiax_monthly.open[:-1])/vfiax_monthly.open[1:]
但我只得到了零:
In [91]: returns.head()
Out[91]:
2003-01-31 NaN
2003-02-28 0
2003-03-31 0
2003-04-30 0
2003-05-30 0
Freq: BM, Name: open
我认为这是因为算术运算在索引上对齐,导致[1:]
和[:-1]
无用。
我的解决方法是:
In [103]: returns = (vfiax_monthly.open[1:].values - vfiax_monthly.open[:-1].values)/vfiax_monthly.open[1:].values
In [104]: returns = pd.Series(returns, index=vfiax_monthly.index[1:])
In [105]: returns.head()
Out[105]:
2003-02-28 -0.015161
2003-03-31 0.009444
2003-04-30 0.076362
2003-05-30 0.049993
2003-06-30 0.012477
Freq: BM
有更好的方法来计算回报吗?我不喜欢转换为数组然后回到Series。
答案 0 :(得分:30)
使用.shift
移动DataFrame / Series中值的索引位置,而不是切片。例如:
returns = (vfiax_monthly.open - vfiax_monthly.open.shift(1))/vfiax_monthly.open.shift(1)
这是pct_change
在发动机罩下正在做的事情。您也可以将它用于其他功能,例如:
(3*vfiax_monthly.open + 2*vfiax_monthly.open.shift(1))/5
答案 1 :(得分:20)
最简单的方法是使用DataFrame.pct_change()方法。
这是一个简单的例子
In[1]: aapl = get_data_yahoo('aapl', start='11/1/2012', end='11/13/2012')
In[2]: appl
Out[2]:
Open High Low Close Volume Adj Close
Date
2012-11-01 598.22 603.00 594.17 596.54 12903500 593.83
2012-11-02 595.89 596.95 574.75 576.80 21406200 574.18
2012-11-05 583.52 587.77 577.60 584.62 18897700 581.96
2012-11-06 590.23 590.74 580.09 582.85 13389900 580.20
2012-11-07 573.84 574.54 555.75 558.00 28344600 558.00
2012-11-08 560.63 562.23 535.29 537.75 37719500 537.75
2012-11-09 540.42 554.88 533.72 547.06 33211200 547.06
2012-11-12 554.15 554.50 538.65 542.83 18421500 542.83
2012-11-13 538.91 550.48 536.36 542.90 19033900 542.90
In[3]: aapl.pct_change()
Out[3]:
Open High Low Close Volume Adj Close
Date
2012-11-01 NaN NaN NaN NaN NaN NaN
2012-11-02 -0.003895 -0.010033 -0.032684 -0.033091 0.658945 -0.033090
2012-11-05 -0.020759 -0.015378 0.004959 0.013558 -0.117186 0.013550
2012-11-06 0.011499 0.005053 0.004311 -0.003028 -0.291453 -0.003024
2012-11-07 -0.027769 -0.027423 -0.041959 -0.042635 1.116864 -0.038263
2012-11-08 -0.023020 -0.021426 -0.036815 -0.036290 0.330747 -0.036290
2012-11-09 -0.036049 -0.013073 -0.002933 0.017313 -0.119522 0.017313
2012-11-12 0.025406 -0.000685 0.009237 -0.007732 -0.445323 -0.007732
2012-11-13 -0.027502 -0.007250 -0.004251 0.000129 0.033244 0.000129
答案 2 :(得分:7)
计算前瞻性回报而没有任何偏见的最佳方法是使用内置函数pd.DataFrame.pct_change()
。在您的情况下,您需要使用的是此功能,因为您有月度数据,并且您正在寻找月度回报。
例如,如果你想查看6个月的回报,你只需设置参数
df.pct_change(periods = 6)
这将为您提供6个月的回报率。
因为您的数据集相对较小,最简单的方法是重新计算您计算数据所需的参数,然后再次使用pct_change()
函数。
然而,由于log
的良好属性,通常使用公式来计算回报(如果您计划对返回序列进行统计):
您将如此实施:
log_return = np.log(vfiax_monthly.open / vfiax_monthly.open.shift())
答案 3 :(得分:1)
还可以混合使用diff
和shift
大熊猫系列方法:
retrun = vfiax_monthly.open.diff()/vfiax_monthly.open.shift(1)