2012-11-14 10 views
12

Ho un dataframe con dati finanziari mensili:calcolare i rendimenti da un dataframe con i dati finanziari

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 

sto cercando di calcolare i rendimenti del genere:

In [90]: returns = (vfiax_monthly.open[1:] - vfiax_monthly.open[:-1])/vfiax_monthly.open[1:] 

Ma sto solo zero:

Penso che sia perché le operazioni aritmetiche si allineano sull'indice e che rende inutile il [1:] e il [:-1].

La mia soluzione è:

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 

C'è un modo migliore per calcolare i rendimenti? Non mi piace la conversione in array e quindi di nuovo in serie.

risposta

25

Invece di affettare, utilizzare .shift per spostare la posizione di indice di valori in una dataframe/Serie. Per esempio:

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

Questo è ciò che pct_change sta facendo sotto il cofano. È inoltre possibile utilizzarlo per altre funzioni ad es .:

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

Si potrebbe anche voler guardare negli rolling e window funzioni per gli altri tipi di analisi dei dati finanziari.

+0

Questo è quello che stavo cercando! –

+4

Penso che la prima riga dovrebbe leggere: restituisce = (vfiax_monthly.open - vfiax_monthly.open.shift (1))/vfiax_monthly.open.shift (1) – DonCristobal

14

Il modo più semplice per eseguire questa operazione è utilizzare il metodo DataFrame.pct_change().

Ecco un rapido esempio

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

Mi piace questa soluzione. Ma è specifico per il mio caso d'uso. Cosa succede se voglio calcolare la media tra ogni paio di mesi (o qualcosa di complicato che non ha una funzione panda integrata): '(vfiax_monthly.open [1:] - vfiax_monthly.open [: - 1])/2' –

+0

Potresti aggiungere un esempio di "qualcosa di complicato" al post originale? Supponendo che tu abbia un 'DateTimeIndex' con frequenza regolare puoi sempre usare' df.resample' per aggregare i dati ad un'altra frequenza regolare (come ogni due mesi) e poi usare 'df.pct_change()' per ottenere i ritorni. Inoltre ci sono varie opzioni per 'pct_change()' [vedi 'periods',' freq'] che ti permettono di specificare quanti punti dati dovrebbero essere usati per calcolare i ritorni ('periodi' imposta su 1, che è il motivo per cui la soluzione ha dato la stessa risposta della tua funzione). – spencerlyon2

+0

'(vfiax_monthly.open [1:] + vfiax_monthly.open [: - 1])/2' è stato un esempio anche se forse c'è una sorta di funzione media della finestra. Ma diciamo che ho bisogno di: '(3 * vfiax_monthly.open [1:] + 2 * vfiax_monthly.open [: - 1])/5'. Ora mi sto rendendo conto che la scelta dell'indice dei risultati è arbitraria, quindi forse la funzione magica che sto cercando non esiste. –

4

Il modo migliore per calcolare retuns che guardano in avanti senza alcuna possibilità di bias è utilizzare la funzione incorporata pd.DataFrame.pct_change(). Nel tuo caso, tutto ciò che devi utilizzare è questa funzione poiché hai dati mensili e stai cercando il rendimento mensile.

Se, per esempio, si desidera visualizzare il ritorno di 6 miglia, si dovrebbe semplicemente impostare il parametro df.pct_change(periods = 6) e questo vi darà il ritorno percentuale di 6 mesi.

Poiché si dispone di un set di dati relativamente piccolo, il modo più semplice è ricampionare sui parametri per i quali è necessario calcolare i dati, quindi utilizzare nuovamente la funzione pct_change().

Problemi correlati