Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ternary operator on arrays in python

Tags:

python

arrays

I am trying to perform the following operation on an array in python:

if true then a else b

I am trying to perform it on one channel of an image. Basically I want to check if a value is greater than 255, if so, return 255 else return the value that is being checked.

here is what I'm trying:

imfinal[:,:,1] = imfinal[:,:,1] if imfinal[:,:,1] <= 255 else 255

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

Is there a better way to perform this operation?

like image 926
shaveenk Avatar asked Mar 28 '15 22:03

shaveenk


3 Answers

Use np.where:

imfinal[:,:,1] = np.where(imfinal[:,:,1] <= 255, imfinal[:,:,1], 255)

As to why you get that error see this: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().

Essentially it becomes ambiguous when you compare arrays using and, or because what if 1 value in the array matches? To compare arrays you should use bitwise operators &, |, ~ for and, or, not respectively.

np.where uses the boolean condition to assign the value in the second param when true, else assigns the 3rd param, see the docs

like image 120
EdChum Avatar answered Oct 04 '22 04:10

EdChum


in your expression:

if imfinal[:,:,1] <= 255

you're trying to compare a scalar with a vector, so it's unlikely to work.

What you actually want is to use map() to do the check on each element of the array:

map(lambda x: x if x <= 255 else 255, imfinal[:,:,1])
like image 29
zmo Avatar answered Oct 04 '22 06:10

zmo


While the other answers cover the general case well, the best solution in your case is probably to use numpy.minimum that does the expansion of the scalar for you:

imfinal[:,:,1] = numpy.minimum(imfinal[:,:,1], 255)
like image 40
Henrik Avatar answered Oct 04 '22 05:10

Henrik