diff options
author | Gerrit Holl <g.holl@reading.ac.uk> | 2015-11-25 20:35:22 +0000 |
---|---|---|
committer | Gerrit Holl <g.holl@reading.ac.uk> | 2015-12-07 16:44:56 +0000 |
commit | 090e85e7bd77e67c8b6bac63fc4b22331eac1950 (patch) | |
tree | d89dce235425b419ef44226122a3eab26f45de8a /numpy | |
parent | db6300726ac9f73282ce8fda5588d958c0f327b4 (diff) | |
download | numpy-090e85e7bd77e67c8b6bac63fc4b22331eac1950.tar.gz |
BUG/TST: Fix for #6723 including test: force fill_value.ndim==0
Fix issue #6723. Given an exotic masked structured array, where one of
the fields has a multidimensional dtype, make sure that, when accessing
this field, the fill_value still makes sense. As it stands prior to this
commit, the fill_value will end up being multidimensional, possibly with
a shape incompatible with the mother array, which leads to broadcasting
errors in methods such as .filled(). This commit uses the first element
of this multidimensional fill value as the new fill value. When more
than one unique value existed in fill_value, a warning is issued.
Also add a test to verify that fill_value.ndim remains 0 after indexing.
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/ma/core.py | 20 | ||||
-rw-r--r-- | numpy/ma/tests/test_core.py | 4 |
2 files changed, 24 insertions, 0 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py index 25e542cd6..0a83284ca 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -3129,6 +3129,26 @@ class MaskedArray(ndarray): if isinstance(indx, basestring): if self._fill_value is not None: dout._fill_value = self._fill_value[indx] + + # If we're indexing a multidimensional field in a + # structured array (such as dtype("(2,)i2,(2,)i1")), + # dimensionality goes up (M[field].ndim == M.ndim + + # len(M.dtype[field].shape)). That's fine for + # M[field] but problematic for M[field].fill_value + # which should have shape () to avoid breaking several + # methods. There is no great way out, so set to + # first element. See issue #6723. + if dout._fill_value.ndim > 0: + if not (dout._fill_value == + dout._fill_value.flat[0]).all(): + warnings.warn( + "Upon accessing multidimensional field " + "{indx:s}, need to keep dimensionality " + "of fill_value at 0. Discarding " + "heterogeneous fill_value and setting " + "all to {fv!s}.".format(indx=indx, + fv=dout._fill_value[0])) + dout._fill_value = dout._fill_value.flat[0] dout._isfield = True # Update the mask if needed if _mask is not nomask: diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index cecdedf26..8d7d9a47d 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -1674,6 +1674,10 @@ class TestFillingValues(TestCase): assert_equal(test, control) control = np.array((0, 0, 0), dtype="int, float, float").astype(ndtype) assert_equal(_check_fill_value(0, ndtype), control) + # but when indexing, fill value should become scalar not tuple + # See issue #6723 + M = masked_array(control) + assert_equal(M["f1"].fill_value.ndim, 0) def test_fillvalue_datetime_timedelta(self): # Test default fillvalue for datetime64 and timedelta64 types. |