Numpy or SciPy Derivative function for non-uniform spacing?
Solution 1
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.
Solution 2
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.
Solution 3
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])
Solution 4
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
user3123955
Updated on June 14, 2022Comments
-
user3123955 almost 2 years
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.
-
user3123955 over 9 yearswhat is a forward and central difference exactly?
-
Saullo G. P. Castro over 9 years@user3123955 check here for example to have an overview about these numerical methods
-
Bruno Feroleto about 9 years
y[1:] - y[:-1]
is provided by the more directly legiblenumpy.diff(y)
. -
Saullo G. P. Castro about 9 years@EOL thank you for the hint, I've updated the answer
-
Bruno Feroleto about 9 yearsGood. 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()
(docs.scipy.org/doc/numpy/reference/generated/…). :) -
Pwnna over 8 yearsHow does this formula even work? I thought center differencing is just (y2 - y0) / (x2 - x0)? Am I missing something?
-
Saullo G. P. Castro over 8 years@Pwnna for the central difference you have also to consider the center point (x1, y1)
-
Luke Davis about 7 years@Pwnna can you tell me where you found that algorithm? Any webpages/textbooks?
-
Jason over 6 yearsSo 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 thisx
as delta x, rather than coordinate ofy
. That's rather a dangeous trap, if you are not paying attention to the version then the results are totally and silently wrong. -
Neinstein over 6 years@Jason indeed, I myself fell for this trap. 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.
-
Jason over 6 yearsI literally hit the submit button to post a new question (here 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?
-
Neinstein over 6 years@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...)
-
Pranshu Gupta over 5 yearsI don't understand, how is the result calculated, i am not able to arrive at [ 2. , 1.65 , 0.31666667, 4.23333333, 5. ]