[SciPy-Dev] Numpy's handling of conditions

Michael Clerx cell at michaelclerx.com
Wed Oct 1 05:43:47 EDT 2014


Thanks!

I'd been looking at the documentation here:

http://docs.scipy.org/doc/numpy/reference/routines.logic.html

I'd never have thought to look at the ufunc page. Perhaps the docs are 
written slightly too much from an experienced numpy'er point of view. 
For example, on the logic page np.any and all are listed first. I can 
see how they're the most important functions, but the first I'd look for 
are and or & not.

Is there a strict protocol for editing the docs?



On 10/01/2014 11:23 AM, Robert Kern wrote:
> On Wed, Oct 1, 2014 at 10:01 AM, Michael Clerx <cell at michaelclerx.com> wrote:
>> Hi Everyone,
>>
>> I'm a bit confused about the way numpy treats conditions and I'm hoping
>> you can help.
>>
>> Starting from this array:
>>
>> x = np.array(x)
>>   >>> x
>> array([1, 2, 3, 2, 1])
>>   >>> x == 1
>> array([ True, False, False, False,  True], dtype=bool)
>>
>> works as expected, but the following is horribly wrong:
>>
>>   >>> x == 1 + x == 3
>> Traceback (most recent call last):
>>     File "<stdin>", line 1, in <module>
>> ValueError: The truth value of an array with more than one element is
>> ambiguous. Use a.any() or a.all()
> Python parses this expression as the following, due to operator precedence:
>
>>>> x == (1 + x) == 3
> The repeated == == has a special meaning in Python. It gets translated to this:
>
>>>> (x == (1+x)) and (x == 3)
> The `and` is the problem here because it tries to evaluate each part
> as a bool, which is forbidden for arrays (hence the ValueError).
>
>> I can live with that, but why do brackets solve this?
>>
>>   >>> (x == 1) + (x == 3)
>> array([ True, False,  True, False,  True], dtype=bool)
>>
>> Which is the same result as
>>
>>   >>> (x == 1) | (x == 3)
>> array([ True, False,  True, False,  True], dtype=bool)
>>
>> It gets a bit weirder:
>>
>>   >>> (x == 1) + (x < 3)
>> array([ True,  True, False,  True,  True], dtype=bool)
>>
>> but
>>
>>   >>> True + True
>> 2
>>
>> Is this the way it's supposed to work? Since it's quite different from
>> python's scalar types, perhaps the documentation should mention it more
>> clearly
> Yes. For most of the binary ufuncs, especially the ones that implement
> the standard arithmetic operators +-*/, we try to make sure that if
> both arguments are the same dtype, the output is also the same dtype
> and do not promote. I believe that there was some discussion about
> this in the past year or so, and it turns out that this is the desired
> semantics for addition over boolean matrices when you start
> implementing linear algebra. The Python `bool` object has other
> concerns, namely backwards compatibility with older versions of Python
> that just used `True = 1; False = 0`.
>
>> (for example, why isn't "or" implemented as a piecewise or).
> Do you mean "or" the Python keyword? This is documented.
>
> http://docs.scipy.org/doc/numpy/reference/ufuncs.html#comparison-functions
>




More information about the SciPy-Dev mailing list