How to efficiently generate an array using 2 arrays and a formula as input with NumPy

Question:

I have two arrays, x and t with n elements (t‘s elements are in strict ascending order, so no dividing by 0) and a formula on which the creation of my new array, v is based:

v[i] = (x[i+1] - x[i]) / (t[i+1] - t[i])

How can I write this in NumPy? I tried using numpy.fromfunction but didn’t manage to make it work.

I did manage to do it using a for loop – but I feel like there’s a better way of doing this:

n = 100000
x = np.random.rand(n)
t = np.random.randint(1, 10, n)
t = t.cumsum()

def gen_v(x, t):
    v = np.zeros(n - 1)
    for i in range(0, n - 1):
        v[i] = (x[i+1] - x[i])/(t[i+1]-t[i])
    return v

v = gen_v(x, t)
%timeit gen_v(x, t)

Outputs

156 ms ± 15 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Asked By: TimerMen

||

Answers:

You can use np.diff():

def gen_v(x,t):
    return np.diff(x)/np.diff(t)

The benchmark give us:

# Your function:
8.45 ms +- 557 us per loop (mean +- std. dev. of 7 runs, 100 loops each)
# My function:
63.4 us +- 1.62 us per loop (mean +- std. dev. of 7 runs, 10000 loops each)
Answered By: obchardon

You could use array slicing

def gen_v(x, t):
    return (x[1:] - x[:-1])/(t[1:] - t[:-1])

Benchmarking yields

# Your Function
62.4 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# Slicing
277 µs ± 3.34 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

On my meager hardware. 😉

Answered By: Invarianz
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.