<br><br><div class="gmail_quote">On Thu, Jun 23, 2011 at 6:21 PM, Mark Wiebe <span dir="ltr">&lt;<a href="mailto:mwwiebe@gmail.com">mwwiebe@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="gmail_quote"><div><div></div><div class="h5">On Thu, Jun 23, 2011 at 7:00 PM, Nathaniel Smith <span dir="ltr">&lt;<a href="mailto:njs@pobox.com" target="_blank">njs@pobox.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div>On Thu, Jun 23, 2011 at 2:44 PM, Robert Kern &lt;<a href="mailto:robert.kern@gmail.com" target="_blank">robert.kern@gmail.com</a>&gt; wrote:<br>
&gt; On Thu, Jun 23, 2011 at 15:53, Mark Wiebe &lt;<a href="mailto:mwwiebe@gmail.com" target="_blank">mwwiebe@gmail.com</a>&gt; wrote:<br>
&gt;&gt; Enthought has asked me to look into the &quot;missing data&quot; problem and how NumPy<br>
&gt;&gt; could treat it better. I&#39;ve considered the different ideas of adding dtype<br>
&gt;&gt; variants with a special signal value and masked arrays, and concluded that<br>
&gt;&gt; adding masks to the core ndarray appears is the best way to deal with the<br>
&gt;&gt; problem in general.<br>
&gt;&gt; I&#39;ve written a NEP that proposes a particular design, viewable here:<br>
&gt;&gt; <a href="https://github.com/m-paradox/numpy/blob/cmaskedarray/doc/neps/c-masked-array.rst" target="_blank">https://github.com/m-paradox/numpy/blob/cmaskedarray/doc/neps/c-masked-array.rst</a><br>
&gt;&gt; There are some questions at the bottom of the NEP which definitely need<br>
&gt;&gt; discussion to find the best design choices. Please read, and let me know of<br>
&gt;&gt; all the errors and gaps you find in the document.<br>
&gt;<br>
&gt; One thing that could use more explanation is how your proposal<br>
&gt; improves on the status quo, i.e. <a href="http://numpy.ma" target="_blank">numpy.ma</a>. As far as I can see, you<br>
&gt; are mostly just shuffling around the functionality that already<br>
&gt; exists. There has been a continual desire for something like R&#39;s NA<br>
&gt; values by people who are very familiar with both R and numpy&#39;s masked<br>
&gt; arrays. Both have their uses, and as Nathaniel points out, R&#39;s<br>
&gt; approach seems to be very well-liked by a lot of users. In essence,<br>
&gt; *that&#39;s* the &quot;missing data problem&quot; that you were charged with: making<br>
&gt; happy the users who are currently dissatisfied with masked arrays. It<br>
&gt; doesn&#39;t seem to me that moving the functionality from <a href="http://numpy.ma" target="_blank">numpy.ma</a> to<br>
&gt; numpy.ndarray resolves any of their issues.<br>
<br>
</div>Speaking as a user who&#39;s avoided <a href="http://numpy.ma" target="_blank">numpy.ma</a>, it wasn&#39;t actually because<br>
of the behavior I pointed out (I never got far enough to notice it),<br>
but because I got the distinct impression that it was a &quot;second-class<br>
citizen&quot; in numpy-land. I don&#39;t know if that&#39;s true. But I wasn&#39;t sure<br>
how solidly things like interactions between numpy and masked arrays<br>
worked, or how , and it seemed like it had more niche uses. So it just<br>
seemed like more hassle than it was worth for my purposes. Moving it<br>
into the core and making it really solid *would* address these<br>
issues...<br></blockquote><div><br></div></div></div><div>These are definitely things I&#39;m trying to address. </div><div class="im"><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


It does have to be solid, though. It occurs to me on further thought<br>
that one major advantage of having first-class &quot;NA&quot; values is that it<br>
preserves the standard looping idioms:<br>
<br>
for i in xrange(len(x)):<br>
  x[i] = np.log(x[i])<br>
<br>
According to the current proposal, this will blow up, but np.log(x)<br>
will work. That seems suboptimal to me.<br></blockquote><div><br></div></div><div>This boils down to the choice between None and a zero-dimensional array as the return value of &#39;x[i]&#39;. This, and the desire that &#39;x[i] == x[i]&#39; should be False if it&#39;s a masked value have convinced me that a zero-dimensional array is the way to go, and your example will work with this choice.</div>
<div class="im">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I do find the argument that we want a general solution compelling. I<br>
suppose we could have a magic &quot;NA&quot; value in Python-land which<br>
magically triggers fiddling with the mask when assigned to numpy<br>
arrays.<br>
<br>
It&#39;s should also be possible to accomplish a general solution at the<br>
dtype level. We could have a &#39;dtype factory&#39; used like:<br>
  np.zeros(10, dtype=np.maybe(float))<br>
where np.maybe(x) returns a new dtype whose storage size is x.itemsize<br>
+ 1, where the extra byte is used to store missingness information.<br>
(There might be some annoying alignment issues to deal with.) Then for<br>
each ufunc we define a handler for the maybe dtype (or add a<br>
special-case to the ufunc dispatch machinery) that checks the<br>
missingness value and then dispatches to the ordinary ufunc handler<br>
for the wrapped dtype.<br></blockquote><div><br></div></div><div>The &#39;dtype factory&#39; idea builds on the way I&#39;ve structured datetime as a parameterized type, but the thing that kills it for me is the alignment problems of &#39;x.itemsize + 1&#39;. Having the mask in a separate memory block is a lot better than having to store 16 bytes for an 8-byte int to preserve the alignment.</div>
</div></blockquote><div><br>Yes, but that assumes it is appended to the existing types in the dtype individually instead of the dtype as a whole. The dtype with mask could just indicate a shadow array, an alpha channel if you will, that is essentially what you are already doing but just probide a different place to track it. <br>
</div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div class="gmail_quote"><div class="im">
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This would require fixing the issue where ufunc inner loops can&#39;t<br>
actually access the dtype object, but we should fix that anyway :-).<br></blockquote><div><br></div></div><div>Certainly true!</div><div><br></div></div></blockquote><div><br>Chuck <br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="gmail_quote"><div></div><br></div></blockquote></div>