endolith
endolith

Reputation: 26803

Is there a faster way to separate the minimum and maximum of two arrays?

In [3]: f1 = rand(100000)
In [5]: f2 = rand(100000)

# Obvious method:
In [12]: timeit fmin = np.amin((f1, f2), axis=0); fmax = np.amax((f1, f2), axis=0)
10 loops, best of 3: 59.2 ms per loop

In [13]: timeit fmin, fmax = np.sort((f1, f2), axis=0)
10 loops, best of 3: 30.8 ms per loop

In [14]: timeit fmin = np.where(f2 < f1, f2, f1); fmax = np.where(f2 < f1, f1, f2)
100 loops, best of 3: 5.73 ms per loop


In [36]: f1 = rand(1000,100,100)

In [37]: f2 = rand(1000,100,100)

In [39]: timeit fmin = np.amin((f1, f2), axis=0); fmax = np.amax((f1, f2), axis=0)
1 loops, best of 3: 6.13 s per loop

In [40]: timeit fmin, fmax = np.sort((f1, f2), axis=0)
1 loops, best of 3: 3.3 s per loop

In [41]: timeit fmin = np.where(f2 < f1, f2, f1); fmax = np.where(f2 < f1, f1, f2)
1 loops, best of 3: 617 ms per loop

Like, maybe there's a way to do both where commands in one step with 2 returns?

Why isn't amin implemented the same way as where, if it's so much faster?

Upvotes: 4

Views: 267

Answers (1)

John Lyon
John Lyon

Reputation: 11420

Use numpy's built in element-wise maximum and minimum - they are faster than where. The notes in the numpy docs for maximum confirm this:

Equivalent to np.where(x1 > x2, x1, x2), but faster and does proper broadcasting.

The line you would want for your first test would be something like:

fmin = np.minimum(f1, f2); fmax = np.maximum(f1, f2)

My own results show this to be quite a bit faster. Note that minimum and maximum will work on any n-dimensional array as long as the two arguments are the same shape.

Using amax                    3.506
Using sort                    1.830
Using where                   0.635
Using numpy maximum, minimum  0.178

Upvotes: 5

Related Questions