I was wondering if numpy or scipy had a method in their libraries to find the numerical derivative of a list of values with non-uniform spacing. The idea is to feed in the timestamps that correspond to the values and then for it to use the timestamps to find the numerical derivative.
5 Answers
You can create your own functions using numpy. For the derivatives using forward differences (edit thanks to @EOL, but note that NumPy's diff()
is not a differentiate function):
def diff_fwd(x, y):
return np.diff(y)/np.diff(x)
"central" differences (it is not necessarily central, depending on your data spacing):
def diff_central(x, y):
x0 = x[:-2]
x1 = x[1:-1]
x2 = x[2:]
y0 = y[:-2]
y1 = y[1:-1]
y2 = y[2:]
f = (x2 - x1)/(x2 - x0)
return (1-f)*(y2 - y1)/(x2 - x1) + f*(y1 - y0)/(x1 - x0)
where y
contains the function evaluations and x
the corresponding "times", such that you can use an arbitrary interval.

- 9,178
- 21
- 65
- 91

- 56,802
- 26
- 179
- 234
-
what is a forward and central difference exactly? – user3123955 Sep 17 '14 at 00:24
-
@user3123955 [check here for example](http://dmpeli.mcmaster.ca/Matlab/Math4Q3/NumMethods/Lecture3-1.html) to have an overview about these numerical methods – Saullo G. P. Castro Sep 17 '14 at 05:58
-
1`y[1:] - y[:-1]` is provided by the more directly legible `numpy.diff(y)`. – Eric O. Lebigot Feb 12 '15 at 07:14
-
1Good. Indeed, `diff()` does not stand for "differentiate" but for "difference". While you're at it, the central differences are already in NumPy too: `numpy.gradient()` (http://docs.scipy.org/doc/numpy/reference/generated/numpy.gradient.html#numpy.gradient). :) – Eric O. Lebigot Feb 13 '15 at 03:29
-
How does this formula even work? I thought center differencing is just (y2 - y0) / (x2 - x0)? Am I missing something? – Pwnna Nov 08 '15 at 05:24
-
@Pwnna for the central difference you have also to consider the center point (x1, y1) – Saullo G. P. Castro Nov 08 '15 at 12:18
-
@Pwnna can you tell me where you found that algorithm? Any webpages/textbooks? – Luke Davis Apr 21 '17 at 04:44
This is a little bit late, but found @dllahr's answer to be very useful and easy to implement with numpy
:
>>> import numpy as np
>>> y = [1, 2, 3, 4, 5]
>>> dy = np.gradient(y)
>>> x = [1, 2, 4, 8, 10]
>>> dx = np.gradient(x)
>>> dy/dx
array([1., 0.66666667, 0.33333333, 0.33333333, 0.5])

- 3,351
- 3
- 25
- 43
This is probably not provided because what you can do instead is take the derivative of your dependent variable (y-values), take the derivative of your independent variable (in your specific case, the timestamps), and then divide the first vector by second.
The definition of the derivative is:
f' = dy / dx
or in your case:
f'(t) = dy / dt
You can use the diff function to calculate each of your numerical dy, the diff function to calculate your numerical dt, and then element divide these arrays to determine f'(t) at each point.

- 421
- 1
- 4
- 13
Scipy's UnivariateSpline.derivative
is a simple way to find the derivative of any data set (x-axis must be ordered such that it is increasing).
x = [1, 3, 8, 10]
y = [0, 8, 12, 4]
z = scipy.interpolate.UnivariateSpline.derivative(x,y)
dz = z.derivative(n)
where n is the order of the derivative
Note that the default order of UnivariateSpline is 3 and equivalent scipy.interpolate.CubicSpline

- 131
- 2
- 11
Since the newest NumPy release (1.13), numpy.gradient
has this feature implemented (documentation):
>>> #only numpy 1.13 and above
>>> import numpy as np
>>> y = [1, 3, 4, 6, 11]
>>> x = [0, 1, 5, 10, 11]
>>> np.gradient(y, x)
array([ 2. , 1.65 , 0.31666667, 4.23333333, 5. ])
Here the values in x
mark the x-coordinates of the y-values in y
.

- 958
- 2
- 11
- 31
-
So this is quite different from its earlier version, innt? For instance I'm using 1.11.3 and its doc suggests that `np.gradient(y, x)` treats this `x` as delta x, rather than coordinate of `y`. That's rather a dangeous trap, if you are not paying attention to the version then the results are totally and silently wrong. – Jason Oct 12 '17 at 03:12
-
@Jason indeed, I myself [fell for this trap](https://stackoverflow.com/q/45776214/5099168). I's only a problem for older releases running code for the new version, as the new version is backwards compatible (afaik). If x was a single number, it'd threat it as delta x. – Neinstein Oct 12 '17 at 05:15
-
I literally hit the submit button to post a new question (here https://stackoverflow.com/q/46701906/2005415) 1 second before noticing your reply. I'm not sure should I delete it or keep it? But it's a very nasty bug, I don't know what to do, writing my own implementation? – Jason Oct 12 '17 at 05:22
-
@Jason I'd leave it, and mention my question in comments as "related". This way the community can make up it's mind and decide whether it's a duplicate. (I don't want to comment this myself, it'd look like rep-hunting...) – Neinstein Oct 12 '17 at 21:58
-
I don't understand, how is the result calculated, i am not able to arrive at [ 2. , 1.65 , 0.31666667, 4.23333333, 5. ] – Pranshu Gupta Sep 08 '18 at 09:18