5

I've read through most of How to convert a boolean array to an int array , but I was still at loss with, how to (most efficiently) convert a numpy bool array to an int array, but with distinct values. For instance, I have:

>>> k=np.array([True, False, False, True, False])
>>> print k
[ True False False  True False]

I'd like this to be converted to an array, where True is say, 2, and False is say 5.

Of course, I can always set up a linear equation:

>>> print 5-k*3
[2 5 5 2 5]

... which, while vectorized, needlessly employs both addition (subtraction) and multiplication; furthermore, if I'd want the opposite values (5 for True and 2 for False), I basically have to use (and recalculate) a different equation:

>>> print 2+k*3
[5 2 2 5 2]

... which is a bit of a readability issue for me.

In essence, this is merely a selection/mapping operation - but one which I'd like done in the numpy domain. How could I do that?

2 Answers 2

10

Seems like numpy.where is exactly what you want:

>>> import numpy as np
>>> k = np.array([True, False, False, True, False])
>>> np.where(k, 2, 5)
array([2, 5, 5, 2, 5])
Sign up to request clarification or add additional context in comments.

2 Comments

Fantastic - thanks a lot, @mgilson! Actually, was looking for something that would work in a recursive np.add (but didn't mention that, because I wanted to reduce the question to "bare essentials" ), this looks like it will do the trick! Thanks again - cheers!
PS: re: "recursive add", now that I've mentioned it (even if it is a bit off-topic for this question): anytime one has anything else other than the "raw" reference in arguments, even just addition, e.g. in a=np.array([1,3,3,4,5,6]); np.add(a[:-1]+0, 2, a[1:]); print a -- numpy will use the "old" values for a[:-1] (in the a[:-1]+0) and will not "recurse" to the "new" previous locations; thus, np.where (and probably any other function) will have the same effect.
1

Well, it seems I have to make a np.array (not a Python list!) containing the two distinct values:

>>> z=np.array([2,5])
>>> print z
[2 5]

... and then I can simply cast the boolean array (k) to int, and use that as selection indices in the "distinct values array" (z):

>>> print z[k.astype(int)]
[5 2 2 5 2]

It is also trivial to change the [2,5] to [5,2], so that is good.

I'm just not sure if this is the right way to do it (that is, maybe there exists something like (pseudocode) k.asdistinctvalues([2,5]) or something like that?)

3 Comments

Going for the sock puppet hat I see? Good move. I need to figure out something to ask a question about too ... ;-)
Heh - honestly, sometimes when I get frustrated of not being able to find an approach with my search terms, I do document stuff on SO in Q&A format, so I can find it next time I type it in a search engine; hope that's not a crime. Cheers! :)
Clearly it isn't a crime, they're even giving incentives to do it -- They've chosen to reward the behavior with a hat!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.