Comparing values ​​in two numpy arrays with 'if'

I'm new to numpy arrays and ran into a problem when comparing one array to another.

I have two arrays, for example:

a = np.array([1,2,3,4,5])
b = np.array([2,4,3,5,2])

      

I want to do something like the following:

if b > a:
    c = b
else:
    c = a

      

so I end up with an array c = np.array ([2,4,3,5,5]).

Otherwise, it can be considered assuming the maximum value for each element of the two arrays.

However, I ran into the error

ValueError: The truth value of an array with more than one element is ambiguous. 
Use a.any() or a.all(). 

      

I've tried using them, but I'm not sure if they are correct for what I want.

Can anyone suggest some guidance on how to resolve this issue?

+3


source to share


4 answers


You are looking for a function np.fmax

. It takes the maximum of the two arrays, ignoring NaNs.

import numpy as np
a = np.array([1, 2, 3, 4, 5])
b = np.array([2, 4, 3, 5, 2])
c = np.fmax(a, b)

      



Output signal

array([2, 4, 3, 5, 5])

      

+11


source


Like pretty much everything else in numpy, comparisons are made element by element, returning an entire array:

>>> b > a
array([ True,  True, False,  True, False], dtype=bool)

      

So, is this true or false? What should the operator do if

?

Numpy's answer is that it shouldn't try to guess, it should just throw an exception.

If you want to assume it is true because at least one value is true, use any

:

>>> if np.any(b > a): print('Yes!')
Yes!

      

If you want to consider it false because not all values ​​are true, use all

:

>>> if np.all(b > a): print('Yes!')

      


But I'm sure you don't want either one or the other. You want to pass the entire array if

/ else

over the array.

Of course, you could wrap the logic if

/ else

for a single value in a function and then explicitly vectorize

it and call it:

>>> def mymax(a, b):
...     if b > a:
...         return b
...     else:
...         return a
>>> vmymax = np.vectorize(mymax)
>>> vmymax(a, b)
array([2, 4, 3, 5, 5])

      



It's worth knowing how to do it ... but very rarely worth it. This is generally a more indirect way of doing it, using natively vectorized functions, and often a more direct way.


One way to do this indirectly is to use the fact that True and False are numeric 1s and 0s:

>>> (b>a)*b + (b<=a)*a
array([2, 4, 3, 5, 5])

      

This will add 1*b[i] + 0*a[i]

when b>a

and 0*b[i] + 1*a[i]

when b<=a

. A bit ugly, but not too hard to understand. There are clearer but more detailed ways to write this.

But let's look for an even better, direct solution.


First, note that your function mymax

will do the same as built-in Python max

for 2 values:

>>> vmymax = np.vectorize(max)
>>> vmymax(a, b)
array([2, 4, 3, 5, 5])

      

Then consider what it might already have for something so useful. And a quick search would look like maximum

:

>>> np.maximum(a, b)
array([2, 4, 3, 5, 5])

      

+5


source


Here's another way to achieve this

c = np.array([y if y>z else z for y,z in zip(a,b)])

      

0


source


The following methods also work:

  • Use numpy.maximum

    >>> np.maximum(a, b)

  • Use numpy.max

    andnumpy.vstack

    >>> np.max(np.vstack(a, b), axis = 0)

0


source







All Articles