summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpierregm <pierregm@localhost>2008-11-21 17:12:47 +0000
committerpierregm <pierregm@localhost>2008-11-21 17:12:47 +0000
commit3a1ffccbafc70bd5d45568fb4dd17de2accf92a4 (patch)
treeda439a87acc8904b4c17a64b00c4d67e0a980e87
parente39cb02e227e168f8b3b55c455820c47e2d6c4c1 (diff)
downloadnumpy-3a1ffccbafc70bd5d45568fb4dd17de2accf92a4.tar.gz
* Prevent the shape of a 1d-singleton to be lost when interacting with masked (bug fix #948)
-rw-r--r--numpy/ma/core.py25
-rw-r--r--numpy/ma/tests/test_core.py85
2 files changed, 92 insertions, 18 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 66958f553..78c6fde81 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -565,7 +565,7 @@ class _MaskedBinaryOperation:
m = mask_or(getmask(a), getmask(b))
(d1, d2) = (get_data(a), get_data(b))
result = self.f(d1, d2, *args, **kwargs).view(get_masked_subclass(a, b))
- if result.size > 1:
+ if len(result.shape):
if m is not nomask:
result._mask = make_mask_none(result.shape)
result._mask.flat = m
@@ -874,7 +874,7 @@ def make_mask(m, copy=False, shrink=True, flag=None, dtype=MaskType):
else:
result = np.array(filled(m, True), dtype=MaskType)
# Bas les masques !
- if shrink and not result.any():
+ if shrink and (not result.dtype.names) and (not result.any()):
return nomask
else:
return result
@@ -1590,17 +1590,17 @@ class MaskedArray(ndarray):
# if getmask(indx) is not nomask:
# msg = "Masked arrays must be filled before they can be used as indices!"
# raise IndexError, msg
- dout = ndarray.__getitem__(ndarray.view(self,ndarray), indx)
+ dout = ndarray.__getitem__(ndarray.view(self, ndarray), indx)
# We could directly use ndarray.__getitem__ on self...
# But then we would have to modify __array_finalize__ to prevent the
# mask of being reshaped if it hasn't been set up properly yet...
# So it's easier to stick to the current version
_mask = self._mask
- if not getattr(dout,'ndim', False):
+ if not getattr(dout, 'ndim', False):
# A record ................
if isinstance(dout, np.void):
mask = _mask[indx]
- if mask.view((bool,len(mask.dtype))).any():
+ if mask.view((bool, len(mask.dtype))).any():
dout = masked_array(dout, mask=mask)
else:
return dout
@@ -1656,7 +1656,7 @@ class MaskedArray(ndarray):
_mask = self._mask = make_mask_none(self.shape, _dtype)
# Now, set the mask to its value.
if nbfields:
- _mask[indx] = tuple([True,] * nbfields)
+ _mask[indx] = tuple([True] * nbfields)
else:
_mask[indx] = True
if not self._isfield:
@@ -1795,7 +1795,7 @@ class MaskedArray(ndarray):
if _mask.size > 1:
axis = 1
else:
- axis=None
+ axis = None
#
try:
return _mask.view((bool_, len(self.dtype))).all(axis)
@@ -2197,7 +2197,7 @@ masked_%(name)s(data = %(data)s,
new_mask = mask_or(other_mask, invalid)
self._mask = mask_or(self._mask, new_mask)
# The following line is potentially problematic, as we change _data...
- np.putmask(self._data,invalid,self.fill_value)
+ np.putmask(self._data, invalid, self.fill_value)
return self
#............................................
def __float__(self):
@@ -2857,7 +2857,7 @@ masked_%(name)s(data = %(data)s,
if not axis:
return (self - m)
else:
- return (self - expand_dims(m,axis))
+ return (self - expand_dims(m, axis))
def var(self, axis=None, dtype=None, out=None, ddof=0):
""
@@ -3124,7 +3124,8 @@ masked_%(name)s(data = %(data)s,
else:
filler = fill_value
idx = np.indices(self.shape)
- idx[axis] = self.filled(filler).argsort(axis=axis,kind=kind,order=order)
+ idx[axis] = self.filled(filler).argsort(axis=axis, kind=kind,
+ order=order)
idx_l = idx.tolist()
tmp_mask = self._mask[idx_l].flat
tmp_data = self._data[idx_l].flat
@@ -3315,11 +3316,11 @@ masked_%(name)s(data = %(data)s,
nbdims = self.ndim
dtypesize = len(self.dtype)
if nbdims == 0:
- return tuple([None]*dtypesize)
+ return tuple([None] * dtypesize)
elif nbdims == 1:
maskedidx = _mask.nonzero()[0].tolist()
if dtypesize:
- nodata = tuple([None]*dtypesize)
+ nodata = tuple([None] * dtypesize)
else:
nodata = None
[operator.setitem(result,i,nodata) for i in maskedidx]
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index 82d7f49e4..606b3c285 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -12,7 +12,6 @@ import warnings
import numpy as np
import numpy.core.fromnumeric as fromnumeric
from numpy import ndarray
-from numpy import int_
from numpy.ma.testutils import *
import numpy.ma.core
@@ -70,7 +69,7 @@ class TestMaskedArray(TestCase):
self.failUnless(not isMaskedArray(x))
self.failUnless(isMaskedArray(xm))
self.failUnless((xm-ym).filled(0).any())
- fail_if_equal(xm.mask.astype(int_), ym.mask.astype(int_))
+ fail_if_equal(xm.mask.astype(int), ym.mask.astype(int))
s = x.shape
assert_equal(np.shape(xm), s)
assert_equal(xm.shape, s)
@@ -594,7 +593,12 @@ class TestMaskedArrayArithmetic(TestCase):
assert_equal(y.shape, x.shape)
assert_equal(y._mask, [True, True])
-
+ def test_arithmetic_with_masked_singleton_on_1d_singleton(self):
+ "Check that we're not losing the shape of a singleton"
+ x = masked_array([1, ])
+ y = x + masked
+ assert_equal(y.shape, x.shape)
+ assert_equal(y.mask, [True, ])
def test_scalar_arithmetic(self):
x = array(0, mask=0)
@@ -1728,7 +1732,7 @@ class TestMaskedArrayMethods(TestCase):
x = array(zip([1,2,3],
[1.1,2.2,3.3],
['one','two','thr']),
- dtype=[('a',int_),('b',float),('c','|S8')])
+ dtype=[('a',int),('b',float),('c','|S8')])
x[-1] = masked
assert_equal(x.tolist(), [(1,1.1,'one'),(2,2.2,'two'),(None,None,None)])
@@ -1953,7 +1957,7 @@ class TestMaskedArrayMathMethodsComplex(TestCase):
m2XX = array(data=XX,mask=m2.reshape(XX.shape))
self.d = (x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX)
- #------------------------------------------------------
+
def test_varstd(self):
"Tests var & std on MaskedArrays."
(x,X,XX,m,mx,mX,mXX,m2x,m2X,m2XX) = self.d
@@ -2017,6 +2021,7 @@ class TestMaskedArrayFunctions(TestCase):
assert_equal(masked_where(not_equal(x,2), x), masked_not_equal(x,2))
assert_equal(masked_where([1,1,0,0,0], [1,2,3,4,5]), [99,99,3,4,5])
+
def test_masked_where_oddities(self):
"""Tests some generic features."""
atest = ones((10,10,10), dtype=float)
@@ -2024,6 +2029,7 @@ class TestMaskedArrayFunctions(TestCase):
ctest = masked_where(btest,atest)
assert_equal(atest,ctest)
+
def test_masked_where_shape_constraint(self):
a = arange(10)
try:
@@ -2141,11 +2147,12 @@ class TestMaskedArrayFunctions(TestCase):
tmp[(xm<=2).filled(True)] = True
assert_equal(d._mask, tmp)
#
- ixm = xm.astype(int_)
+ ixm = xm.astype(int)
d = where(ixm>2, ixm, masked)
assert_equal(d, [-9,-9,-9,-9, -9, 4, -9, -9, 10, -9, -9, 3])
assert_equal(d.dtype, ixm.dtype)
+
def test_where_with_masked_choice(self):
x = arange(10)
x[3] = masked
@@ -2286,6 +2293,70 @@ class TestMaskedArrayFunctions(TestCase):
test = make_mask_descr(ntype)
assert_equal(test, np.dtype(np.bool))
+
+ def test_make_mask(self):
+ "Test make_mask"
+ # w/ a list as an input
+ mask = [0,1]
+ test = make_mask(mask)
+ assert_equal(test.dtype, MaskType)
+ assert_equal(test, [0,1])
+ # w/ a ndarray as an input
+ mask = np.array([0,1], dtype=np.bool)
+ test = make_mask(mask)
+ assert_equal(test.dtype, MaskType)
+ assert_equal(test, [0,1])
+ # w/ a flexible-type ndarray as an input - use default
+ mdtype = [('a', np.bool), ('b', np.bool)]
+ mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
+ test = make_mask(mask)
+ assert_equal(test.dtype, MaskType)
+ assert_equal(test, [1,1])
+ # w/ a flexible-type ndarray as an input - use input dtype
+ mdtype = [('a', np.bool), ('b', np.bool)]
+ mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
+ test = make_mask(mask, dtype=mask.dtype)
+ assert_equal(test.dtype, mdtype)
+ assert_equal(test, mask)
+ # w/ a flexible-type ndarray as an input - use input dtype
+ mdtype = [('a', np.float), ('b', np.float)]
+ bdtype = [('a', np.bool), ('b', np.bool)]
+ mask = np.array([(0, 0), (0, 1)], dtype=mdtype)
+ test = make_mask(mask, dtype=mask.dtype)
+ assert_equal(test.dtype, bdtype)
+ assert_equal(test, np.array([(0, 0), (0, 1)], dtype=bdtype))
+
+
+ def test_mask_or(self):
+ # Initialize
+ mtype = [('a', np.bool), ('b', np.bool)]
+ mask = np.array([(0, 0), (0, 1), (1, 0), (0, 0)], dtype=mtype)
+ # Test using nomask as input
+ test = mask_or(mask, nomask)
+ assert_equal(test, mask)
+ test = mask_or(nomask, mask)
+ assert_equal(test, mask)
+ # Using False as input
+ test = mask_or(mask, False)
+ assert_equal(test, mask)
+ # Using True as input. Won't work, but keep it for the kicks
+ #test = ma.mask_or(mask, True)
+ #control = np.array([(1, 1), (1, 1), (1, 1), (1, 1)], dtype=mtype)
+ #assert_equal(test, control)
+ # Using another array w/ the same dtype
+ other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=mtype)
+ test = mask_or(mask, other)
+ control = np.array([(0, 1), (0, 1), (1, 1), (0, 1)], dtype=mtype)
+ assert_equal(test, control)
+ # Using another array w/ a different dtype
+ othertype = [('A', np.bool), ('B', np.bool)]
+ other = np.array([(0, 1), (0, 1), (0, 1), (0, 1)], dtype=othertype)
+ try:
+ test = mask_or(mask, other)
+ except ValueError:
+ pass
+
+
#------------------------------------------------------------------------------
class TestMaskedFields(TestCase):
@@ -2408,6 +2479,8 @@ class TestMaskedFields(TestCase):
assert_equal_records(a[-2]._mask, a._mask[-2])
+#------------------------------------------------------------------------------
+
class TestMaskedView(TestCase):
#
def setUp(self):