summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorGerrit Holl <g.holl@reading.ac.uk>2015-11-25 20:35:22 +0000
committerGerrit Holl <g.holl@reading.ac.uk>2015-12-07 16:44:56 +0000
commit090e85e7bd77e67c8b6bac63fc4b22331eac1950 (patch)
treed89dce235425b419ef44226122a3eab26f45de8a /numpy
parentdb6300726ac9f73282ce8fda5588d958c0f327b4 (diff)
downloadnumpy-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.py20
-rw-r--r--numpy/ma/tests/test_core.py4
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.