2012-11-14 61 views
12

我有每月財務數據,一個數據框:計算從財務數據的數據幀返回

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。

回答

25

相反切片,用.shift移動在數據幀/系列值的索引位置。例如:

returns = (vfiax_monthly.open - vfiax_monthly.open.shift(1))/vfiax_monthly.open 

這就是pct_change正在做的事情。您也可以將其用於其他功能例如爲:

(3*vfiax_monthly.open + 2*vfiax_monthly.open.shift(1))/5 

您可能還需要尋找到rollingwindow功能其他類型的金融數據的分析。

+0

這就是我一直在尋找的! –

+4

我認爲第一行應該是: returns =(vfiax_monthly.open - vfiax_monthly.open.shift(1))/ vfiax_monthly.open.shift(1) – DonCristobal

14

最簡單的方法是使用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 
+0

我喜歡這個解決方案。但具體到我的用例。如果我想計算每兩個月之間的平均值(或者沒有內置熊貓函數的複雜內容):'(vfiax_monthly.open [1:] - vfiax_monthly.open [: - 1])/ 2' –

+0

您能否在原始文章中添加「複雜的東西」的例子?假設你有一個具有固定頻率的'DateTimeIndex',你總是可以使用'df.resample'以另一個常規頻率(比如每兩個月)聚合數據,然後使用'df.pct_change()'來獲得收益。也有'pct_change()'[見'periods','freq']的多種選項,允許您指定應該使用多少個數據點來計算返回值('句號'默認爲1,這就是解決方案的原因給出了與你的功能相同的答案)。 – spencerlyon2

+0

'(vfiax_monthly.open [1:] + vfiax_monthly。打開[: - 1])/ 2'就是一個例子,儘管可能有某種窗口平均函數。但是讓我們說我需要:'(3 * vfiax_monthly.open [1:] + 2 * vfiax_monthly.open [: - 1])/ 5'。現在我意識到結果索引的選擇是任意的,所以也許我所尋找的魔法函數不存在。 –

4

計算前瞻性retuns不帶偏見的任何機會,最好的辦法是使用內置的功能pd.DataFrame.pct_change()。在你的情況下,所有你需要使用的是這個函數,因爲你有每月的數據,你正在尋找每月的回報。

如果說,你想看看6蛾回報,你只需設置參數 df.pct_change(periods = 6),這將給你6個月的百分比回報。

由於您的數據集相對較小,最簡單的方法是對需要計算數據的參數進行重新採樣,然後再次使用pct_change()函數。