[Numpy-discussion] adding booleans

josef.pktd at gmail.com josef.pktd at gmail.com
Sat Jun 8 08:48:37 EDT 2013


On Sat, Jun 8, 2013 at 5:18 AM, Sebastian Berg
<sebastian at sipsolutions.net> wrote:
> On Sat, 2013-06-08 at 00:48 +0100, Nathaniel Smith wrote:
>> On 7 Jun 2013 21:58, <josef.pktd at gmail.com> wrote:
>> >
>> > Interesting observation, (while lurking on a pull request)
>> >
>> > >>> np.add.reduce(np.arange(5)<3)
>> > 3
>> > >>> np.add((np.arange(5)<3), (np.arange(5)<3))
>> > array([ True,  True,  True, False, False], dtype=bool)
>> >
>> >
>> > I often use summing of an array of boolean but didn't know the
>> second behavior
>>
>> ...yeah weird. My gut reaction is that it's a bug. Addition on bools
>> should either be an error, undefined but doable via an implicit upcast
>> to int (analogous to calling np.sin on an int array triggering an
>> upcast to float), or xor (i.e., addition mod 2). But apparently we're
>> inconsistent - add.reduce upcasts, and add.__call__, uh... upcasts and
>> then downcasts, maybe? It's like if np.sin on an int array returned
>> ints? I can't see how to get the quoted behaviour in any conceptually
>> coherent way. But maybe I'm missing something.
>>
> I believe these are implemented as ufunc-machinery special cases for the
> add ufunc reduction methods. This ensures that the sums output integer
> type is at least a `np.int_` if the input is integer or bool. With a
> future warning, it seems plausible for bools to have `bool + bool = int`
> (code might (ab)use it as a logical operation) I guess, but `int16 +
> int16` should probably stay int16? While sum over it being larger avoids
> overflow accidents.

I think bool + bool with overflow result would be consistent with the rest.
if this is the rule
"reduce/accumulate operations upcast, simple operators on 2 identical
types don't"

but bool + bool has a result that is neither python nor overflow, AFAICS

I never looked carefully at what the expected overflow behavior is
with "small" dtypes (since I avoid them)

In python 3, division is now the odd case

>>> np.uint8(1) - np.uint8(2)

Warning (from warnings module):
  File "C:\Programs\Python32\Lib\idlelib\idle.pyw", line 1
    try:
RuntimeWarning: overflow encountered in ubyte_scalars
>>> 255
>>> np.uint8(1) / np.uint8(2)
0.5
>>> np.uint8(1) * np.uint8(2)
2
>>> np.uint8(150) * np.uint8(2)
44



Josef

> Another (additionally good) thing would be to have better integer
> overflow warnings here, but it seems likely that for the sake of
> backward compatibility these special cases can't be easily changed in
> any case.
>
> - Sebastian
>
>> -n
>>
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion at scipy.org
>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion



More information about the NumPy-Discussion mailing list