Reputation: 42329
Say I have an ordered array/list like this one:
a = [0.2, 0.35, 0.88, 1.2, 1.33, 1.87, 2.64, 2.71, 3.02]
I want to find the largest difference between adjacent elements efficiently. In this case it would be (2.64 - 1.87) = 0.77
.
I could use a for
loop but I wonder if there's a more elegant/efficient solution. Solutions using numpy
are welcomed.
TEST
OK, I took all the answers and tested them (see code at the bottom). These are the results in seconds:
0.0867638587952 0.118239144757 mark
0.00386190414429 0.118239144757 Padraic
0.00108003616333 0.118239144757 mtrw
0.0790281295776 0.118239144757 yurib
0.000712156295776 0.118239144757 elyase
which means elyase is the winner by several orders of magnitude. Thank you all!
MWE:
import numpy as np
import time
a = np.sort(np.random.uniform(0., 1000., 100000))
tik = time.time()
val = max(y - x for x,y in zip(a, a[1:]))
print time.time() - tik, val, 'mark'
tik = time.time()
val = np.ediff1d(a).max()
print time.time() - tik, val, 'Padraic'
tik = time.time()
val = np.max(np.abs(np.diff(a)))
print time.time() - tik, val, 'mtrw'
tik = time.time()
val = max(a[i+1]-a[i] for i in range(len(a)-1))
print time.time() - tik, val, 'yurib'
tik = time.time()
val = np.diff(a).max()
print time.time() - tik, val, 'elyase'
Upvotes: 1
Views: 1430
Reputation: 20695
If we want to get a little crazy about performance, we can use numba
:
import numba
@autojit
def max_consecutive_diff(x):
prev = x[0]
diff_max = 0.0
for i in range(1, len(x)):
cur = x[i]
diff = cur - prev
if diff > diff_max:
diff_max = diff
prev = cur
return diff_max
Here's a speed test. Generating data with
>>> x = np.sort(np.random.sample(1e7))
we get:
>>> %timeit max_consecutive_diff(x)
100 loops, best of 3: 11.9 ms per loop
>>> %timeit np.max(np.diff(x))
10 loops, best of 3: 33.9 ms per loop
Of course, these are milliseconds for ten-million long input array. I'd just stick with the np.diff
solution, but it's always cool to see how well numba
can do.
Upvotes: 2
Reputation: 180401
a = [0.2, 0.35, 0.88, 1.2, 1.33, 1.87, 2.64, 2.71, 3.02]
import numpy as np
print(np.ediff1d(a).max())
0.77
Difference between diff
and ediff1d
is ediff1d will flatten before comparing:
In [18]: y = [[1, 2, 4], [1, 6, 24]]
In [19]: print(np.ediff1d(y))
[ 1 2 -3 5 18]
In [20]: print(np.diff(y))
[[ 1 2]
[ 5 18]]
Upvotes: 1
Reputation: 308148
I can't claim it's more efficient or more elegant, but it's different:
>>> max(y - x for x,y in zip(a, a[1:]))
0.77
Upvotes: 4