Skip to content Skip to sidebar Skip to footer

Numpy Diff Inverted Operation?

Working with numpy.diff function, suppose this simple case: >>> x = np.array([1, 2, 4, 7, 0]) >>> x_diff = np.diff(x) array([ 1, 2, 3, -7]) How can I get easil

Solution 1:

Concatenate with the first element and then use cumsum -

np.r_[x[0], x_diff].cumsum()

For concatenating, we can also use np.hstack, like so -

np.hstack((x[0], x_diff)).cumsum()

Or with np.concatenate for the concatenation -

np.concatenate(([x[0]], x_diff)).cumsum()

Solution 2:

Performance benchmark

As Divakar proposed a few solutions and I was wondering, what I should take, here the performance benchmark. I also added this answer.

result

Long story short - just use: np.concatenate(([x[0]], x_diff)).cumsum().

enter image description here

x: problem size, y: computing time for 1000 runs

code

import timeit
import random
import numpy as np
import matplotlib.pyplot as plt

cmds = [
    'np.r_[x[0], x_diff].cumsum()',
    'np.hstack((x[0], x_diff)).cumsum()',
    'np.concatenate(([x[0]], x_diff)).cumsum()',
    'csp0 = np.zeros(shape=(len(x) + 1,)); np.cumsum(x, out=csp0[1:])',
    ]
test_range = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6]
# test_range = [1e0, 1e1, 1e2]

ts = np.empty((len(cmds), len(test_range)), dtype=float)
for tt, size_float inenumerate(test_range):
    size = round(size_float)
    print('array size:', size)
    x = np.random.randint(low=0, high=100, size=size)
    x_diff = np.diff(x)

    n_trials = 1000for cc, cmd inenumerate(cmds):

        t = timeit.Timer(cmd, globals={**globals(), **locals()})
        t = t.timeit(n_trials)
        ts[cc, tt] = t
        print('time for {:d}x \"{:}\": {:.6f}'.format(n_trials, cmd, t))


fig, ax = plt.subplots(1, 1, figsize=(15, 10))
for cc, cmd inenumerate(cmds):
    ax.plot(test_range, ts[cc, :], label=cmd)
    print(cmd)
ax.legend()
ax.set_xscale('log')
ax.set_yscale('log')

output

array size: 1timefor1000x "np.r_[x[0], x_diff].cumsum()": 0.011935timefor1000x "np.hstack((x[0], x_diff)).cumsum()": 0.006159timefor1000x "np.concatenate(([x[0]], x_diff)).cumsum()": 0.003221timefor1000x "csp0 = np.zeros(shape=(len(x) + 1,)); np.cumsum(x, out=csp0[1:])": 0.003482array size: 10timefor1000x "np.r_[x[0], x_diff].cumsum()": 0.009031timefor1000x "np.hstack((x[0], x_diff)).cumsum()": 0.006170timefor1000x "np.concatenate(([x[0]], x_diff)).cumsum()": 0.003082timefor1000x "csp0 = np.zeros(shape=(len(x) + 1,)); np.cumsum(x, out=csp0[1:])": 0.003467array size: 100timefor1000x "np.r_[x[0], x_diff].cumsum()": 0.009754timefor1000x "np.hstack((x[0], x_diff)).cumsum()": 0.006332timefor1000x "np.concatenate(([x[0]], x_diff)).cumsum()": 0.003296timefor1000x "csp0 = np.zeros(shape=(len(x) + 1,)); np.cumsum(x, out=csp0[1:])": 0.004249array size: 1000timefor1000x "np.r_[x[0], x_diff].cumsum()": 0.010550timefor1000x "np.hstack((x[0], x_diff)).cumsum()": 0.008595timefor1000x "np.concatenate(([x[0]], x_diff)).cumsum()": 0.005414timefor1000x "csp0 = np.zeros(shape=(len(x) + 1,)); np.cumsum(x, out=csp0[1:])": 0.006916array size: 10000timefor1000x "np.r_[x[0], x_diff].cumsum()": 0.029658timefor1000x "np.hstack((x[0], x_diff)).cumsum()": 0.028389timefor1000x "np.concatenate(([x[0]], x_diff)).cumsum()": 0.024410timefor1000x "csp0 = np.zeros(shape=(len(x) + 1,)); np.cumsum(x, out=csp0[1:])": 0.034652array size: 100000timefor1000x "np.r_[x[0], x_diff].cumsum()": 0.221405timefor1000x "np.hstack((x[0], x_diff)).cumsum()": 0.219564timefor1000x "np.concatenate(([x[0]], x_diff)).cumsum()": 0.215796timefor1000x "csp0 = np.zeros(shape=(len(x) + 1,)); np.cumsum(x, out=csp0[1:])": 0.310225array size: 1000000timefor1000x "np.r_[x[0], x_diff].cumsum()": 2.660822timefor1000x "np.hstack((x[0], x_diff)).cumsum()": 2.664244timefor1000x "np.concatenate(([x[0]], x_diff)).cumsum()": 2.636382timefor1000x "csp0 = np.zeros(shape=(len(x) + 1,)); np.cumsum(x, out=csp0[1:])": 3.770557
np.r_[x[0], x_diff].cumsum()
np.hstack((x[0], x_diff)).cumsum()
np.concatenate(([x[0]], x_diff)).cumsum()
csp0 = np.zeros(shape=(len(x) +1,)); np.cumsum(x, out=csp0[1:])

Post a Comment for "Numpy Diff Inverted Operation?"