0

I need to convert a list of instants a to a list of increments da, for example from a list

a=[1.,3.,4.,8.]

I want the list

da=[2.,1.,4.]

Doing it "manually" is quite straightforward:

da=[]
for i in range(len(a)-1):
    da.append(a[i+1]-a[i])

Does python offer a more synthetic and elegant way to do this, without the for loop?

A solution in the case a is a numpy array rather than a list would also be fine.

3sm1r
  • 520
  • 4
  • 19

2 Answers2

2

Numpy has a diff() function that does just this:

import numpy as np

a = np.array([1.,3.,4.,8.])

np.diff(a)
# array([2., 1., 4.])
Mark
  • 90,562
  • 7
  • 108
  • 148
1

Since you have the numpy tag:

import numpy as np

a=np.array([1., 3., 4., 8.])

da = a[1:] - a[:-1]
da
array([2., 1., 4.])

While one can think that np.diff is faster, it is actually slightly slower, checking performance:

import timeit
import pandas as pd

def timeit_diff(s):
    a = np.random.rand(s)

    t0 = timeit.default_timer()
    np.diff(a)
    return timeit.default_timer() - t0

def timeit_shift(s):
    a = np.random.rand(s)
    t0 = timeit.default_timer()
    a[1:] - a[:-1]
    return timeit.default_timer() - t0

sizes = [10**i for i in range(10)]

times = [[s, timeit_diff(s), timeit_shift(s)] for s in sizes]

df = pd.DataFrame(times, columns=['size', 'diff_method', 'difference'])

df.set_index('size', inplace=True)
df
            diff_method  difference
size                               
1              0.000031    0.000004
10             0.000011    0.000002
100            0.000009    0.000010
1000           0.000027    0.000004
10000          0.000020    0.000013
100000         0.000827    0.001420
1000000        0.007460    0.009606
10000000       0.061235    0.061254
100000000      0.641381    0.597128
1000000000    23.763331   18.087844

df.plot(figsize=(12,8))

enter image description here

FBruzzesi
  • 6,385
  • 3
  • 15
  • 37