On Sunday 20 January 2008 16:32:40 you wrote:
> Pierre,
>
> The attached script shows how one can make a masked array with different
> dimensions for the mask than for the data.  I presume this is a bug.  It
> is triggered by the present code in the matplotlib quiver function.

Yep, bug indeed. Thanks for pointing that out ! 
The following patch should take care of the problem. (In short, a getmask 
function was used instead of getmaskarray).
Note that the patch takes also into account elements I had sent to Stefan 2 
weeks ago, that were not ported yet to the SVN: I still can't commit to the 
numpy/branches/maskedarray.
Let me know how it works, and thanks again for your time.
P.
Index: /home/backtopop/workspace/numpy_maskedarray/numpy/ma/core.py
===================================================================
--- /home/backtopop/workspace/numpy_maskedarray/numpy/ma/core.py	(revision 4737)
+++ /home/backtopop/workspace/numpy_maskedarray/numpy/ma/core.py	(working copy)
@@ -14,42 +14,47 @@
 
 :author: Pierre Gerard-Marchant
 :contact: pierregm_at_uga_dot_edu
+:version: $Id: core.py 341 2007-12-25 16:23:05Z backtopop $
 """
-__author__ = "Pierre GF Gerard-Marchant"
+__author__ = "Pierre GF Gerard-Marchant ($Author: backtopop $)"
+__version__ = '1.0'
+__revision__ = "$Revision: 341 $"
+__date__     = '$Date: 2007-12-25 11:23:05 -0500 (Tue, 25 Dec 2007) $'
+
 __docformat__ = "restructuredtext en"
 
 __all__ = ['MAError', 'MaskType', 'MaskedArray',
            'bool_', 'complex_', 'float_', 'int_', 'object_',
            'abs', 'absolute', 'add', 'all', 'allclose', 'allequal', 'alltrue',
-           'amax', 'amin', 'anom', 'anomalies', 'any', 'arange',
-           'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2',
-           'arctanh', 'argmax', 'argmin', 'argsort', 'around',
-           'array', 'asarray','asanyarray',
+               'amax', 'amin', 'anom', 'anomalies', 'any', 'arange',
+               'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2',
+               'arctanh', 'argmax', 'argmin', 'argsort', 'around',
+               'array', 'asarray','asanyarray',
            'bitwise_and', 'bitwise_or', 'bitwise_xor',
            'ceil', 'choose', 'compressed', 'concatenate', 'conjugate',
-           'cos', 'cosh', 'count',
+               'cos', 'cosh', 'count',
            'default_fill_value', 'diagonal', 'divide', 'dump', 'dumps',
            'empty', 'empty_like', 'equal', 'exp',
            'fabs', 'fmod', 'filled', 'floor', 'floor_divide','fix_invalid',
            'getmask', 'getmaskarray', 'greater', 'greater_equal', 'hypot',
            'ids', 'inner', 'innerproduct',
-           'isMA', 'isMaskedArray', 'is_mask', 'is_masked', 'isarray',
+               'isMA', 'isMaskedArray', 'is_mask', 'is_masked', 'isarray',
            'left_shift', 'less', 'less_equal', 'load', 'loads', 'log', 'log10',
-           'logical_and', 'logical_not', 'logical_or', 'logical_xor',
+               'logical_and', 'logical_not', 'logical_or', 'logical_xor',
            'make_mask', 'make_mask_none', 'mask_or', 'masked',
-           'masked_array', 'masked_equal', 'masked_greater',
-           'masked_greater_equal', 'masked_inside', 'masked_less',
-           'masked_less_equal', 'masked_not_equal', 'masked_object',
-           'masked_outside', 'masked_print_option', 'masked_singleton',
-           'masked_values', 'masked_where', 'max', 'maximum', 'mean', 'min',
-           'minimum', 'multiply',
+               'masked_array', 'masked_equal', 'masked_greater',
+               'masked_greater_equal', 'masked_inside', 'masked_less',
+               'masked_less_equal', 'masked_not_equal', 'masked_object',
+               'masked_outside', 'masked_print_option', 'masked_singleton',
+               'masked_values', 'masked_where', 'max', 'maximum', 'mean', 'min',
+               'minimum', 'multiply',
            'negative', 'nomask', 'nonzero', 'not_equal',
            'ones', 'outer', 'outerproduct',
            'power', 'product', 'ptp', 'put', 'putmask',
            'rank', 'ravel', 'remainder', 'repeat', 'reshape', 'resize',
-           'right_shift', 'round_',
+               'right_shift', 'round_',
            'shape', 'sin', 'sinh', 'size', 'sometrue', 'sort', 'sqrt', 'std',
-           'subtract', 'sum', 'swapaxes',
+               'subtract', 'sum', 'swapaxes',
            'take', 'tan', 'tanh', 'transpose', 'true_divide',
            'var', 'where',
            'zeros']
@@ -178,6 +183,26 @@
     else:
         raise TypeError, 'Unsuitable type for calculating minimum.'
 
+
+def _check_fill_value(fill_value, dtype):        
+    descr = numpy.dtype(dtype).descr
+    if fill_value is None:
+        if len(descr) > 1:
+            fill_value = [default_fill_value(numeric.dtype(d[1])) 
+                          for d in descr]
+        else:
+            fill_value = default_fill_value(dtype)
+    else:
+        fval = numpy.resize(narray(fill_value,copy=False,dtype=object_),
+                            len(descr))
+        if len(descr) > 1:
+            fill_value = [numpy.asarray(f).astype(d[1]).item()
+                          for (f,d) in zip(fval, descr)]
+        else:
+            fill_value = narray(fval, copy=False, dtype=dtype).item()
+    return fill_value
+
+
 def set_fill_value(a, fill_value):
     """Set the filling value of a, if a is a masked array.  Otherwise,
     do nothing.
@@ -187,7 +212,7 @@
 
     """
     if isinstance(a, MaskedArray):
-        a.set_fill_value(fill_value)
+        a._fill_value = _check_fill_value(fill_value, a.dtype)
     return
 
 def get_fill_value(a):
@@ -212,6 +237,7 @@
         return t1
     return None
 
+
 #####--------------------------------------------------------------------------
 def filled(a, value = None):
     """Return a as an array with masked data replaced by value.  If
@@ -1058,7 +1084,7 @@
 
     Construction:
         x = MaskedArray(data, mask=nomask, dtype=None, copy=True,
-        fill_value=None, keep_mask=True, hard_mask=False, shrink=True)
+        fill_value=None, keep_mask = True, hard_mask=False, shrink=True)
 
     *Parameters*:
         data : {var}
@@ -1162,11 +1188,7 @@
                     _data._sharedmask = False
 
         # Update fill_value.......
-        if fill_value is None:
-            _data._fill_value = getattr(data, '_fill_value',
-                                        default_fill_value(_data))
-        else:
-            _data._fill_value = fill_value
+        _data._fill_value = _check_fill_value(fill_value, _data.dtype)
         # Process extra options ..
         _data._hardmask = hard_mask
         _data._baseclass = _baseclass
@@ -1210,7 +1232,7 @@
         if context is not None:
             result._mask = result._mask.copy()
             (func, args, _) = context
-            m = reduce(mask_or, [getmask(arg) for arg in args])
+            m = reduce(mask_or, [getmaskarray(arg) for arg in args])
             # Get the domain mask................
             domain = ufunc_domain.get(func, None)
             if domain is not None:
@@ -1266,6 +1288,10 @@
             dout = dout.view(type(self))
             # Inherit attributes from self
             dout._update_from(self)
+            # Check the fill_value ....
+            if isinstance(indx, basestring):
+                fvindx = list(self.dtype.names).index(indx)
+                dout._fill_value = self._fill_value[fvindx]
             # Update the mask if needed
             if m is not nomask:
                 if isinstance(indx, basestring):
@@ -1459,9 +1485,7 @@
         If value is None, use a default based on the data type.
 
         """
-        if value is None:
-            value = default_fill_value(self)
-        self._fill_value = value
+        self._fill_value = _check_fill_value(value,self.dtype)
 
     fill_value = property(fget=get_fill_value, fset=set_fill_value,
                           doc="Filling value.")
@@ -2769,7 +2793,6 @@
     for x in arrays:
         if getmask(x) is not nomask:
             break
-    else:
         return data
     # OK, so we have to concatenate the masks
     dm = numpy.concatenate([getmaskarray(a) for a in arrays], axis)
@@ -3207,4 +3230,5 @@
 def loads(strg):
     "Load a pickle from the current string."""
     return cPickle.loads(strg)
-
+       
+        
\ No newline at end of file
Index: /home/backtopop/workspace/numpy_maskedarray/numpy/ma/tests/test_core.py
===================================================================
--- /home/backtopop/workspace/numpy_maskedarray/numpy/ma/tests/test_core.py	(revision 4737)
+++ /home/backtopop/workspace/numpy_maskedarray/numpy/ma/tests/test_core.py	(working copy)
@@ -3,12 +3,12 @@
 
 :author: Pierre Gerard-Marchant
 :contact: pierregm_at_uga_dot_edu
-:version: $Id: test_core.py 3473 2007-10-29 15:18:13Z jarrod.millman $
+:version: $Id: test_core.py 344 2008-01-06 21:35:14Z backtopop $
 """
-__author__ = "Pierre GF Gerard-Marchant ($Author: jarrod.millman $)"
+__author__ = "Pierre GF Gerard-Marchant ($Author: backtopop $)"
 __version__ = '1.0'
-__revision__ = "$Revision: 3473 $"
-__date__     = '$Date: 2007-10-29 17:18:13 +0200 (Mon, 29 Oct 2007) $'
+__revision__ = "$Revision: 344 $"
+__date__     = '$Date: 2008-01-06 16:35:14 -0500 (Sun, 06 Jan 2008) $'
 
 import types
 import warnings
@@ -32,18 +32,6 @@
 from test_old_ma import *
 restore_path()
 
-class TestNoMask(NumpyTestCase):
-    def test_no_inplace(self):
-        x = nomask
-        y = x
-        x += 1
-        assert x != y
-
-    def test_no_copy(self):
-        x = nomask
-        y = x.copy()
-        assert x is y
-
 #..............................................................................
 class TestMA(NumpyTestCase):
     "Base test class for MaskedArrays."
@@ -352,6 +340,11 @@
         assert(xm[0].ptp() is masked)
         assert(xm[0].ptp(0) is masked)
         assert(xm[0].ptp(-1) is masked)
+        #
+        x = array([1,2,3], mask=True)
+        assert(x.min() is masked)
+        assert(x.max() is masked)
+        assert(x.ptp() is masked)
     #........................
     def test_addsumprod (self):
         "Tests add, sum, product."
@@ -390,6 +383,16 @@
         xmym = concatenate((xm,ym),1)
         assert_equal(numpy.concatenate((x,y),1), xmym)
         assert_equal(numpy.concatenate((xm.mask,ym.mask),1), xmym._mask)
+        #
+        x=zeros(2)
+        y=array(ones(2),mask=[False,True])
+        z = concatenate((x,y))
+        assert_array_equal(z,[0,0,1,1])
+        assert_array_equal(z.mask,[False,False,False,True])
+        z = concatenate((y,x))
+        assert_array_equal(z,[1,1,0,0])
+        assert_array_equal(z.mask,[False,True,False,False])
+
     #........................
     def test_indexing(self):
         "Tests conversions and indexing"
@@ -756,6 +759,19 @@
         dma_3 = MaskedArray(dma_1, mask=[1,0,0,0]*6)
         fail_if_equal(dma_3.mask, dma_1.mask)
 
+    def test_backwards(self):
+        "Tests backward compatibility with numpy.core.ma"
+        import numpy.core.ma as nma
+        x = nma.arange(5)
+        x[2] = nma.masked
+        X = masked_array(x, mask=x._mask)
+        assert_equal(X._mask, x.mask)
+        assert_equal(X._data, x._data)
+        X = masked_array(x)
+        assert_equal(X._data, x._data)
+        assert_equal(X._mask, x.mask)
+        assert_equal(getmask(x), [0,0,1,0,0])
+
     def test_pickling(self):
         "Tests pickling"
         import cPickle
@@ -774,10 +790,27 @@
         assert(isinstance(a_pickled._data,numpy.matrix))
     #
     def test_fillvalue(self):
-        "Check that we don't lose the fill_value"
+        "Having fun with the fill_value"
         data = masked_array([1,2,3],fill_value=-999)
         series = data[[0,2,1]]
         assert_equal(series._fill_value, data._fill_value)
+        #
+        mtype = [('f',float_),('s','|S3')]
+        x = array([(1,'a'),(2,'b'),(numpy.pi,'pi')], dtype=mtype)
+        x.fill_value=999
+        assert_equal(x.fill_value,[999.,'999'])
+        assert_equal(x['f'].fill_value, 999)
+        assert_equal(x['s'].fill_value, '999')
+        #
+        x.fill_value=(9,'???')
+        assert_equal(x.fill_value, (9,'???'))
+        assert_equal(x['f'].fill_value, 9)
+        assert_equal(x['s'].fill_value, '???')
+        #
+        x = array([1,2,3.1])
+        x.fill_value = 999
+        assert_equal(numpy.asarray(x.fill_value).dtype, float_)
+        assert_equal(x.fill_value, 999.)
     #
     def test_asarray(self):
         (x, y, a10, m1, m2, xm, ym, z, zm, xf) = self.d
@@ -793,6 +826,7 @@
         assert_equal(data_fixed._mask, [1., 0., 1.])
     #
     def test_imag_real(self):
+        "Check complex"
         xx = array([1+10j,20+2j], mask=[1,0])
         assert_equal(xx.imag,[10,2])
         assert_equal(xx.imag.filled(), [1e+20,2])
@@ -800,6 +834,29 @@
         assert_equal(xx.real,[1,20])
         assert_equal(xx.real.filled(), [1e+20,20])
         assert_equal(xx.real.dtype, xx._data.real.dtype)
+    #
+    def test_ndmin(self):
+        "Check the use of ndmin"
+        x = array([1,2,3],mask=[1,0,0], ndmin=2)
+        assert_equal(x.shape,(1,3))
+        assert_equal(x._data,[[1,2,3]])
+        assert_equal(x._mask,[[1,0,0]])
+    #
+    def test_record(self):
+        "Check record access"
+        mtype = [('f',float_),('s','|S3')]
+        x = array([(1,'a'),(2,'b'),(numpy.pi,'pi')], dtype=mtype)
+        x[1] = masked
+        #
+        (xf, xs) = (x['f'], x['s'])
+        assert_equal(xf.data, [1,2,numpy.pi])
+        assert_equal(xf.mask, [0,1,0]) 
+        assert_equal(xf.dtype, float_)
+        assert_equal(xs.data, ['a', 'b', 'pi'])
+        assert_equal(xs.mask, [0,1,0])
+        assert_equal(xs.dtype, '|S3')
+    #
+    
 
 #...............................................................................
 
@@ -1348,37 +1405,7 @@
         putmask(mxx, mask, values)
         assert_equal(mxx, [1,2,30,4,5,60])
 
-    def test_ndmin(self):
-        x = array([1,2,3],mask=[1,0,0], ndmin=2)
-        assert_equal(x.shape,(1,3))
-        assert_equal(x._data,[[1,2,3]])
-        assert_equal(x._mask,[[1,0,0]])
 
-    def test_sumprod_masked(self):
-        x = masked_array([1,2,3], mask=True)
-        z = x.min()
-        assert(x.sum() is masked)
-        assert(x.prod() is masked)
-
-    def test_fancy_dtype(self):
-        mtype = [('f',float_),('s','|S3')]
-        x = array([(1,'a'),(2,'b'),(numpy.pi,'pi')], dtype=mtype)
-        x[1] = masked
-        x['f'] = 17
-
-    def test_concat(self):
-         x=zeros(2)
-         y=array(ones(2),mask=[False,True])
-
-         z = concatenate((x,y))
-         assert_array_equal(z,[0,0,1,1])
-         assert_array_equal(z.mask,[False,False,False,True])
-
-         z = concatenate((y,x))
-         assert_array_equal(z,[1,1,0,0])
-         assert_array_equal(z.mask,[False,True,False,False])
-
-
 #..............................................................................
 
 ###############################################################################
Index: /home/backtopop/workspace/numpy_maskedarray/numpy/ma/mrecords.py
===================================================================
--- /home/backtopop/workspace/numpy_maskedarray/numpy/ma/mrecords.py	(revision 4737)
+++ /home/backtopop/workspace/numpy_maskedarray/numpy/ma/mrecords.py	(working copy)
@@ -3,12 +3,12 @@
 
 :author: Pierre Gerard-Marchant
 :contact: pierregm_at_uga_dot_edu
-:version: $Id: mrecords.py 3473 2007-10-29 15:18:13Z jarrod.millman $
+:version: $Id: mrecords.py 344 2008-01-06 21:35:14Z backtopop $
 """
-__author__ = "Pierre GF Gerard-Marchant ($Author: jarrod.millman $)"
+__author__ = "Pierre GF Gerard-Marchant ($Author: backtopop $)"
 __version__ = '1.0'
-__revision__ = "$Revision: 3473 $"
-__date__     = '$Date: 2007-10-29 17:18:13 +0200 (Mon, 29 Oct 2007) $'
+__revision__ = "$Revision: 344 $"
+__date__     = '$Date: 2008-01-06 16:35:14 -0500 (Sun, 06 Jan 2008) $'
 
 import sys
 import types
@@ -34,6 +34,8 @@
 from numpy.ma.core import default_fill_value, masked_print_option
 
 import warnings
+import logging
+logging.basicConfig(level=logging.DEBUG, format='%(name)-15s %(levelname)s %(message)s',)
 
 reserved_fields = ['_data','_mask','_fieldmask', 'dtype']
 
@@ -249,7 +251,7 @@
         _localdict = self.__dict__
         _data = self._data
         # We want a field ........
-        if isinstance(indx, str):
+        if isinstance(indx, basestring):
             obj = _data[indx].view(MaskedArray)
             obj._set_mask(_localdict['_fieldmask'][indx])
             # Force to nomask if the mask is empty
@@ -693,10 +695,10 @@
 ################################################################################
 if __name__ == '__main__':
     import numpy as N
-    from numpy.ma.testutils import assert_equal
+    from maskedarray.testutils import assert_equal
     if 1:
         d = N.arange(5)
-        m = numpy.ma.make_mask([1,0,0,1,1])
+        m = maskedarray.make_mask([1,0,0,1,1])
         base_d = N.r_[d,d[::-1]].reshape(2,-1).T
         base_m = N.r_[[m, m[::-1]]].T
         base = masked_array(base_d, mask=base_m).T
_______________________________________________
Numpy-discussion mailing list
Numpy-discussion@scipy.org
http://projects.scipy.org/mailman/listinfo/numpy-discussion

Reply via email to