On Fri, Nov 4, 2011 at 11:59 AM, Pauli Virtanen <<a href="mailto:pav@iki.fi">pav@iki.fi</a>> wrote:<br>><br>> I have a feeling that if you don't start by mathematically defining the<br>> scalar operations first, and only after that generalize them to arrays,<br>
> some conceptual problems may follow.<br>><br><br>Yes.  I was going to mention this point as well.<br><br>><br>> For shorthand, we can refer to the above choices with the nomenclature<br>><br>>    <shorthand> ::= <propagation> <destructivity> <payload_type><br>
>    <propagation> ::= "P" | "N"<br>>    <destructivity> ::= "d" | "n" | "s"<br>>    <payload_type> ::= "S" | "E" | "C"<br>
><br>> That makes 2 * 3 * 3 = 18 different ways to construct consistent<br>> behavior. Some of them might make sense, the problem is to find out which :)<br>><br><br>This is great for the discussion, IMO.  The self-destructive assignment hasn't come up at all, so I'm guessing we can probably ignore it.<br>
<br>---<br><br>Can you be a bit more explicit on the payload types?  Let me try, respond with corrections if necessary.<br><br>"S" is singleton and in the case of "missing" data, we take it to mean that we only care that data is missing and not *how* missing the data is.<br>
<br>>>> x = MISSING<br>>>> -x  # unary<br>MISSING<br>>>> x + 3  # binary<br>MISSING<br><br>"E" means that we acknowledge that we want to track the "how", but that we aren't interested in it. So raise an error.<br>
In the case of ignored data, we might have:<br><br>>>> x = 2<br>>>> ignore(x)<br>>>> x<br>IGNORED(2)<br>>>> -x<br>Error<br>>>> x + 3<br>Error<br><br>"C" means that we acknowledge that we want to track the "how", and that we are interested in it.  So do the computations.<br>
<br>>>> x = 2<br>>>> ignore(x)<br>>>> -x<br>IGNORED(-2)<br>>>> x + 3<br>IGNORED(5)<br><br>Did I get that mostly right?<br><br>> NAN and NA apparently fall into the PdS class.<br>><br>
<br>Here is where I think we need ot be a bit more careful.  It is true that we want NAN and MISSING to propagate, but then we additionally want to ignore it sometimes.  This is precisely why we have functions like nansum.  Although people are well-aware of this desire, I think this thread has largely conflated the issues when discussing "propagation".<br>
<br>To push this forward a bit, can I propose that IGNORE behave as:   PnC<br><br>>>> x = np.array([1, 2, 3])<br>>>> y = np.array([10, 20, 30])<br>>>> ignore(x[2])<br>>>> x<br>[1, IGNORED(2), 3]<br>
>>> x + 2<br>[3, IGNORED(4), 5]<br>>>> x + y<br>[11, IGNORED(22), 33]<br>>>> z = x.sum()<br>>>> z<br>IGNORED(6)<br>>>> unignore(z)<br>>>> z<br>6<br>>>> x.sum(skipIGNORED=True)<br>
4<br><br>When done in this fashion, I think it is perfectly fine for "masks to be unmasked".<br><br>