12

I have a list of prices where I am trying to calculate the change in percentage of each number. I calculated the differences with

    prices = [30.4, 32.5, 31.7, 31.2, 32.7, 34.1, 35.8, 37.8, 36.3, 36.3, 35.6]

    def f():
        for i in range(len(prices)):
            print(prices[i]-prices[i-1])

Which returns the differences like

    2.1
    -0.8
    -0.5
    ...

I know the change in percentage would be ((i-(i-1))/(i-1) *100, but I don't know how to incorporate that into the script. Any help would be much appreciated.

Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
  • You probably want `range(1, len(prices))`- otherwise the first thing it prints will be the difference between the last and first elements of the list. – David Robinson Oct 03 '12 at 00:07
  • You have the change percentage equation wrong... You may be thinking of a % error equation which goes like abs(x-y)/x, where x is the correct value in theory, but difference is abs(x-y) / average x, y – jeremy Oct 03 '12 at 00:08
  • You're right, David. I changed the range as you suggested and amended the last line to `print ((prices[i]-prices[i-1])/prices[i-1]*100)` –  Oct 03 '12 at 00:26
  • It's a bit late to ask, but how could I convert the output of f() into a list? –  Oct 03 '12 at 00:42

3 Answers3

23

If you haven't been exposed to the pandas library in Python (http://pandas.pydata.org/), you should definitely check it out.

Doing this is as easy as:

import pandas as pd
prices = [30.4, 32.5, 31.7, 31.2, 32.7, 34.1, 35.8, 37.8, 36.3, 36.3, 35.6]

price_series = pd.Series(prices)
price_series.pct_change()
badgley
  • 1,657
  • 1
  • 13
  • 19
16

Try this:

prices = [30.4, 32.5, 31.7, 31.2, 32.7, 34.1, 35.8, 37.8, 36.3, 36.3, 35.6]

for a, b in zip(prices[::1], prices[1::1]):
    print 100 * (b - a) / a

Edit: If you want this as a list, you could do this:

print [100 * (b - a) / a for a, b in zip(prices[::1], prices[1::1])]
arshajii
  • 127,459
  • 24
  • 238
  • 287
  • Edit: After the first couple of values, the numbers go off: 6.90789473684 ,-1.57728706625 ,4.28134556575 , 5.58659217877 , 0.0 , 0.0 , 0.0 , 0.0 , -5.5900621118 , 0.327868852459 , 0.0 –  Oct 03 '12 at 00:15
  • What output were you expecting? – arshajii Oct 03 '12 at 00:36
  • Maybe I copied you code wrong, I don't know. I have the correct output here: 6.90789473684, -2.46153846154 , -1.57728706625 , 4.80769230769 , 4.28134556575 , 4.9853372434 , 5.58659217877 , -3.96825396825 , 0.0 , -1.92837465565 , 0.0. However, do you know how I could convert all those individual outputs into a single list? –  Oct 03 '12 at 00:46
  • 1
    That is exactly what this outputs, except for the last 0.0 -- but shouldn't there be only 10 outputs (not 11)?? – arshajii Oct 03 '12 at 00:50
  • Hm. You're right. I must've entered it wrong. My actual prices list is longer than what I entered here, so I guess I entered a different list when giving you those numbers. I'd like the output to be like ['6.90789473684', '-2.46153846154' , '-1.57728706625' , '4.80769230769'...] instead of individually though. –  Oct 03 '12 at 00:55
2

Though definitely not the most elegant way, if you'd like to define a function it would look something like this:

def pctc(Q):
    output = [0]
    for i in range(len(Q)):
        if i > 0:
            increase = Q[i]-Q[i-1]
            percentage = (increase/Q[i]) * 100
            output.append(percentage)
    return(output)

There's probably even a better way to do that function, but it's clear at least. :))