40

How do I compute the derivative of an array, y (say), with respect to another array, x (say) - both arrays from a certain experiment?

e.g.

y = [1,2,3,4,4,5,6] and x = [.1,.2,.5,.6,.7,.8,.9];

I want to get dy/dx!

imbr
  • 6,226
  • 4
  • 53
  • 65
Adams Gwazah
  • 401
  • 1
  • 4
  • 3
  • 1
    Functions have derivatives, not sets of values. If we defined a function `dydx(x=[.1,.2,.5,.6,.7,.8,.9], y=[1,2,3,4,4,5,6])`, what would you expect the return value to look like? – chepner May 30 '13 at 16:53
  • Do you wish to calculate derivative function? or just values over given intervals? – nims May 30 '13 at 16:54
  • 2
    use NumPy: https://github.com/tiagopereira/python_tips/wiki/Numpy%3A-numerical-derivatives – japreiss May 30 '13 at 16:55
  • 1
    in your case it looks like `y = 10x` => derivative is `y=10` I think ... Im not sure I understood the question – Joran Beasley May 30 '13 at 16:56
  • 1
    Dy / dx means difference in Y, divided by difference in X, otherwise known as the slope between the two points (x_1, y_1) and (x_2, y_2). Just subtract two adjacent elements in `y[]`, and divide by the difference in the two corresponding elements in `x[]`. – 3Dave May 25 '18 at 20:17

4 Answers4

49

Use numpy.diff

If dx is constant

from numpy import diff
dx = 0.1
y = [1, 2, 3, 4, 4, 5, 6]
dy = diff(y)/dx
print dy 
array([ 10.,  10.,  10.,   0.,  10.,  10.])

dx is not constant (your example)

from numpy import diff
x = [.1, .2, .5, .6, .7, .8, .9]
y = [1, 2, 3, 4, 4, 5, 6]
dydx = diff(y)/diff(x)
print dydx 
[10., 3.33333,  10. ,   0. , 10. ,  10.]

Note that this approximated "derivative" has size n-1 where n is your array/list size.

Don't know what you are trying to achieve but here are some ideas:

imbr
  • 6,226
  • 4
  • 53
  • 65
19

use numpy.gradient()

Please be aware that there are more advanced way to calculate the numerical derivative than simply using diff. I would suggest to use numpy.gradient, like in this example.

import numpy as np
from matplotlib import pyplot as plt

# we sample a sin(x) function
dx = np.pi/10
x = np.arange(0,2*np.pi,np.pi/10)

# we calculate the derivative, with np.gradient
plt.plot(x,np.gradient(np.sin(x), dx), '-*', label='approx')

# we compare it with the exact first derivative, i.e. cos(x)
plt.plot(x,np.cos(x), label='exact')
plt.legend()
Intrastellar Explorer
  • 3,005
  • 9
  • 52
  • 119
giotto
  • 532
  • 3
  • 15
5

I'm assuming this is what you meant:

>>> from __future__ import division
>>> x = [.1,.2,.5,.6,.7,.8,.9]
>>> y = [1,2,3,4,4,5,6]
>>> from itertools import izip
>>> def pairwise(iterable): # question 5389507
...     "s -> (s0,s1), (s2,s3), (s4, s5), ..."
...     a = iter(iterable)
...     return izip(a, a)
... 
>>> for ((a, b), (c, d)) in zip(pairwise(x), pairwise(y)):
...   print (d - c) / (b - a)
... 
10.0
10.0
10.0
>>>

question 5389507 link

That is, define dx as the difference between adjacent elements in x.

Community
  • 1
  • 1
tsm
  • 3,598
  • 2
  • 21
  • 35
  • 3
    I love functional programming as much as the next guy, but this answer is needlessly complicated. – Tim Kuipers Aug 29 '18 at 07:32
  • 1
    This computes every other difference, which is clearly not what the question is asking for. If you want to debate 'clearly' given the succientness of the OP, note this answer doesn't handle the fact that x and y have an odd number of elements in his question. Answers using np.diff are correct. – Roger Labbe Mar 15 '21 at 19:54
4

numpy.diff(x) computes

the difference between adjacent elements in x

just like in the answer by @tsm. As a result you get an array which is 1 element shorter than the original one. This of course makes sense, as you can only start computing the differences from the first index (1 "history element" is needed).

>>> x = [1,3,4,6,7,8]
>>> dx = numpy.diff(x)
>>> dx
array([2, 1, 2, 1, 1])

>>> y = [1,2,4,2,3,1]
>>> dy = numpy.diff(y)
>>> dy
array([ 1,  2, -2,  1, -2])

Now you can divide those 2 resulting arrays to get the desired derivative.

>>> d = dy / dx
>>> d
array([ 0.5,  2. , -1. ,  1. , -2. ])

If for some reason, you need a relative (to the y-values) growth, you can do it the following way:

>>> d / y[:-1]
array([ 0.5       ,  1.        , -0.25      ,  0.5       , -0.66666667])

Interpret as 50% growth, 100% growth, -25% growth, etc.

Full code:

import numpy
x = [1,3,4,6,7,8]
y = [1,2,4,2,3,1]
dx = numpy.diff(x)
dy = numpy.diff(y)
d = dy/dx
  • 1
    Please provide some sort of explanation, along with the code. – Nick Jan 25 '18 at 20:07
  • 1
    While this might be a valid answer, it would be better if you elaborate on that, so that feature visitors can learn from this. – Pablo Jan 25 '18 at 23:20
  • @Pablo Please read [this meta](https://meta.stackoverflow.com/questions/287563/youre-doing-it-wrong-a-plea-for-sanity-in-the-low-quality-posts-queue). While code-only answers aren't great, they generally shouldn't be deleted either – Machavity Jan 25 '18 at 23:46
  • @Machavity thanks for the link, I'll keep that in mind. – Pablo Jan 25 '18 at 23:48
  • 1
    Thank you for notifying me, @Nick . I updated my answer, hope it makes sense. – user3554809 Jan 27 '18 at 10:04