14

Given a series of event times v, I can create their interval durations using np.diff(v). Is there a way to have np.diff assume the series starts with an implicit 0., so that it produces an array that has the same length as v?

A manual workaround is:

def diff_from_zero(v):
    return np.diff(np.hstack(([0.], v)))

Is there a way to use diff or another function to have the same result?

6
  • This or directly concatenating diff's result to the first element of your original array which is more or less the same
    – Emilien
    Commented Jan 26, 2017 at 15:12
  • 1
    I don't have an answer but I notice that the hstack doc says, 'you should prefer np.concatenate or np.stack.'
    – Bill Bell
    Commented Jan 26, 2017 at 16:02
  • Thanks! hstack does in fact support the shorthand np.hstack((0, v)) and concatenate not.
    – bluss
    Commented Jan 26, 2017 at 16:17
  • I like your manual approach. There are many ways of prefixing a vector before diffing (zero hstack((0,v)), clamp hstack((v[0],v)), wrap hstack((v[-1],v)), mirror hstack((v[1],v))) and it’s application-dependent. Spelling it out like this should be fine. Commented Jan 26, 2017 at 20:24
  • @Emilien Ah that's not the same thing. I figure my title was ambiguous
    – bluss
    Commented Jan 26, 2017 at 21:12

3 Answers 3

24

As of 2019, np.diff has the arguments prepend and append that can add a certain value to the array before differentiation. See the docs

This would append the first value to the array, hence the diff operation would return something of len(t) that starts with 0.

>>> t = np.array([1.1, 2.0, 4.5, 4.9, 5.2])
>>> np.diff(t, prepend=t[0])
array([0. , 0.9, 2.5, 0.4, 0.3])

The prepend argument can take other values.

2
  • Perfect! Exactly what I was looking for. It is very practical to have all derivatives with the same dimensions as the input. Commented Sep 22, 2022 at 21:47
  • An extension to @Matias answer: append = t[0] argument returns a difference of first and last element t[0]-t[-1] and adheres it to the diff array as the last element: array([ 0.9, 2.5, 0.4, 0.3, -4.1])`
    – aVral
    Commented May 12 at 9:36
6

Given for example:

t = np.array([1.1, 2.0, 4.5, 4.9, 5.2])

We want to compute the consecutive differences in t, including the diff from 0. to the first element in t.

The question gave this way of accomplishing this:

>>> np.diff(np.hstack((0, t)))

And it could be this too:

>>> np.hstack((t[0], np.diff(t)))

But the obscurely-named function ediff1d can do it in one function call:

>>> np.ediff1d(t, to_begin=t[0])
array([ 1.1,  0.9,  2.5,  0.4,  0.3])

Prepending t[0] to the result is the same as computing the difference t[0] - 0., of course. (Assuming t is nonempty).


Timings (not the motivation of the question, but I was curious)

import numpy as np
t = np.random.randn(10000)
%timeit np.diff(np.concatenate(([0], t)))
10000 loops, best of 3: 23.1 µs per loop
%timeit np.diff(np.hstack((0, t)))
10000 loops, best of 3: 31.2 µs per loop
%timeit np.ediff1d(t, to_begin=t[0])
10000 loops, best of 3: 92 µs per loop
2
  • 1
    The code for both diff and ediff1d is python that you can easily study. diff is simpler. In the base case it is the difference between two slices, t[1:]-t[:-1].
    – hpaulj
    Commented Jan 26, 2017 at 22:08
  • 1
    The equivalent of hstack is np.concatenate(([0],t)). hstack just makes sure the inputs are atleast_1d arrays.
    – hpaulj
    Commented Jan 26, 2017 at 22:15
0

Follow-up of Matias' answer for arrays of more than one axis :

def np_diff(arr: np.array, axis: int):
    return np.diff(
        arr, 
        axis=axis, 
        prepend=np.expand_dims(np.take(arr, 0, axis=axis), axis=axis)
    )

Not the answer you're looking for? Browse other questions tagged or ask your own question.