On Fri, 2013-06-07 at 20:29 -0400, [email protected] wrote: > On Fri, Jun 7, 2013 at 8:08 PM, <[email protected]> wrote: > > On Fri, Jun 7, 2013 at 7:48 PM, Nathaniel Smith <[email protected]> wrote: > >> On 7 Jun 2013 21:58, <[email protected]> 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. > > > > The first case is perfectly good behavior. I always "knew"/assumed > > that in python bool are 0-1 ints with all the calculation rules. > > I only found the second one a surprise (found by Pauli) > > > >>>> reduce(np.add, [ True, True, True, False, False]) > > True > >>>> reduce(lambda x, y: x+y, [ True, True, True, False, False]) > > 3 > > > > > > The following we use *very* often: > > > > proportion = (x > 0).mean() > > n_valid = isfinite(x).sum() > > > > cond = cond1 * cond2 > > > > in python: trick indexing with 0-1 bool > >>>> ["True", "False"][False] > > 'True' > > python indexing with np.bool > >>> ["True", "False"][np.bool(False)] > 'True' > >>> ["True", "False"][np.bool(True)] > 'False' >
Uhh, damnit, I thought this was not the case. The correct code would be `np.bool_(False)`, but it works as well. I guess for the sake of compatibility with Python bools it must work... Within NumPy indexing with bools however seems wrong to me. This creates a bit of dilemma in my mind, because I thought it would be fine to just say that python bools cannot be safely interpreted as integers (i.e. ignore that they support the index operator), but seeing this we would have to check for `np.bool_` too. Also note that `operator.index(np.array(True))` actually fails currently, which is a (harmless) inconsistency. It seems to mean that we will either have a 0-d special case (allow 0darr[np.bool_] as boolean indexing but otherwise use it as int), or need extra checks for `np.bool_` to disallow both python and numpy bools. - Sebastian > operation between numbers and bool > >>> a = np.array([ True, True, True, False, False]) > >>> a * range(5) > array([0, 1, 2, 0, 0]) > >>> a * range(1, 6) > array([1, 2, 3, 0, 0]) > >>> a + range(5) > array([1, 2, 3, 3, 4]) > > > multiply and maximum don't need to upcast because the result stays 0-1 > > >>> reduce(np.multiply, [ True, True, True, False, False]) > False > >>> np.multiply.reduce([ True, True, True, False, False]) > 0 > > >>> np.maximum.reduce([ True, True, True, False, False]) > True > >>> np.maximum.accumulate([ True, True, True, False, False]) > array([ True, True, True, True, True], dtype=bool) > > also fine > >>> np.add.accumulate([ True, True, True, False, False]) > array([1, 2, 3, 3, 3]) > > ----------- > > I think the only "weird" and inconsistent one is that bool1 + bool2 > does not upcast to int > > Josef > > > > > Josef > > > >> > >> -n > >> > >> > >> _______________________________________________ > >> NumPy-Discussion mailing list > >> [email protected] > >> http://mail.scipy.org/mailman/listinfo/numpy-discussion > >> > _______________________________________________ > NumPy-Discussion mailing list > [email protected] > http://mail.scipy.org/mailman/listinfo/numpy-discussion > _______________________________________________ NumPy-Discussion mailing list [email protected] http://mail.scipy.org/mailman/listinfo/numpy-discussion
