How to conditionally combine two numpy arrays of the same shape

This sounds simple, and I think I’m overcomplicating this in my mind.

I want to make an array whose elements are generated from two source arrays of the same shape, depending on which element in the source arrays is greater.

to illustrate:

import numpy as np
array1 = np.array((2,3,0))
array2 = np.array((1,5,0))

array3 = (insert magic)
>> array([2, 5, 0))

I can’t work out how to produce an array3 that combines the elements of array1 and array2 to produce an array where only the greater of the two array1/array2 element values is taken.

Any help would be much appreciated. Thanks.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

We could use NumPy built-in np.maximum, made exactly for that purpose –

np.maximum(array1, array2)

Another way would be to use the NumPy ufunc np.max on a 2D stacked array and max-reduce along the first axis (axis=0)

np.max([array1,array2],axis=0)

Timings on 1 million datasets –

In [271]: array1 = np.random.randint(0,9,(1000000))

In [272]: array2 = np.random.randint(0,9,(1000000))

In [274]: %timeit np.maximum(array1, array2)
1000 loops, best of 3: 1.25 ms per loop

In [275]: %timeit np.max([array1, array2],axis=0)
100 loops, best of 3: 3.31 ms per loop

# @Eric Duminil's soln1
In [276]: %timeit np.where( array1 > array2, array1, array2)
100 loops, best of 3: 5.15 ms per loop

# @Eric Duminil's soln2
In [277]: magic = lambda x,y : np.where(x > y , x, y)

In [278]: %timeit magic(array1, array2)
100 loops, best of 3: 5.13 ms per loop

Extending to other supporting ufuncs

Similarly, there’s np.minimum for finding element-wise minimum values between two arrays of same or broadcastable shapes. So, to find element-wise minimum between array1 and array2, we would have :

np.minimum(array1, array2)

For a complete list of ufuncs that support this feature, please refer to the docs and look for the keyword : element-wise. Grep-ing for those, I got the following ufuncs :

add, subtract, multiply, divide, logaddexp, logaddexp2, true_divide,
floor_divide, power, remainder, mod, fmod, divmod, heaviside, gcd,
lcm, arctan2, hypot, bitwise_and, bitwise_or, bitwise_xor, left_shift,
right_shift, greater, greater_equal, less, less_equal, not_equal,
equal, logical_and, logical_or, logical_xor, maximum, minimum, fmax,
fmin, copysign, nextafter, ldexp, fmod

Method 2

If your condition ever becomes more complex, you could use np.where:

import numpy as np
array1 = np.array((2,3,0))
array2 = np.array((1,5,0))
array3 = np.where( array1 > array2, array1, array2)
# array([2, 5, 0])

You could replace array1 > array2 with any condition. If all you want is the maximum, go with @Divakar’s answer.

And just for fun :

magic = lambda x,y : np.where(x > y , x, y)
magic(array1, array2)
# array([2, 5, 0])


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x