2012-04-19 6 views
5

Ho un elenco di numeri in virgola mobile e voglio generare un altro elenco di ritorni di periodo dal mio primo elenco.Qual è il modo più pignolo per calcolare le variazioni di percentuale su un elenco di numeri

Questa è una corsa del mulino implementazione (non testato - e, ovviamente, nessun errore di controllo/gestione):

a = [100,105,100,95,100] 

def calc_period_returns(values, period): 
    output = [] 
    startpos, endpos = (period, len(values)-1) 

    while True: 
     current = values[startpos] 
     previous = values[startpos-period] 
     ret = 100*((current-previous)/(1.0*previous)) 
     output.append(ret) 
     startpos += period 
     if startpos > endpos: 
      break 
    return output 


calc_period_returns(a,1) 

# Expected output: 
# [5.0, -4.7619047619047619, -5.0, 5.2631578947368416] 

C'è un modo più divinatorio di fare questo - magari utilizzando di lista e le mappe?

+1

qual è il risultato desiderato? –

+0

@RomanBodnarchuk: Ho aggiornato la domanda con un risultato previsto –

+0

vedi aggiornamento alla risposta. –

risposta

10

Qui si va:

>>> [100.0 * a1/a2 - 100 for a1, a2 in zip(a[1:], a)] 
[5.0, -4.7619047619047592, -5.0, 5.2631578947368354] 

Dal momento che si desidera confrontare gli elementi vicini di una lista, è meglio creare un elenco di coppie che ti interessa, in questo modo:

>>> a = range(5) 
>>> a 
[0, 1, 2, 3, 4] 
>>> zip(a, a[1:]) 
[(0, 1), (1, 2), (2, 3), (3, 4)] 

Dopo di che è solo un semplice calcolo matematico per estrarre una variazione percentuale da una coppia di numeri.

+0

Sei stato a conoscenza di questa terminologia o hai decifrato dal suo codice? – Abhijit

+0

@Abhijit un po ':) Appena mappato l'input all'output :) –

+0

Solo una piccola FYI, questo fallisce con la divisione per zero se uno qualsiasi dei numeri è zero. – mikkom

15

Non so quanto sarà grande la tua lista di numeri, ma se hai intenzione di elaborare grandi quantità di numeri, dovresti dare un'occhiata a numpy. L'effetto collaterale è che i calcoli sembrano molto più semplici.

Con NumPy, di creare un array per i dati

>>> import numpy as np 
>>> a = np.array([100,105,100,95,100], dtype=float) 

e lavorare con gli array come se fossero semplici numeri

>>> np.diff(a)/a[:-1] * 100. 
[ 5.   -4.76190476 -5.   5.26315789] 
+1

In realtà, quello che vuoi veramente è 'np.diff (a)/np.abs (a [: - 1]) * 100. Inoltre, un elemento in a potrebbe essere 0, quindi per evitare di dividere per 0 errore potresti voler fare qualcosa come 'a [a == 0] = 0,000000001' –

Problemi correlati