Skip to content

Commit

Permalink
BUG: Fix boolean indexing to previous behavior by adding an additiona…
Browse files Browse the repository at this point in the history
…l check before using the new code path. Add tests.
  • Loading branch information
teoliphant committed Jun 21, 2012
1 parent 134174c commit db1701b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
14 changes: 8 additions & 6 deletions doc/release/2.0.0-notes.rst
Expand Up @@ -24,12 +24,9 @@ The default casting rule for UFunc out= parameters has been changed from
rule are likely bugs, so this change may expose previously undetected
errors in projects that depend on NumPy.

Full-array boolean indexing used to allow boolean arrays with a size
non-broadcastable to the array size. Now it forces this to be broadcastable.
Since this affects some legacy code, this change will require discussion
during alpha or early beta testing, and a decision to either keep the
stricter behavior, or add in a hack to allow the previous behavior to
work.
Full-array boolean indexing has been optimized to use a different,
optimized code path. This code path should produce the same results,
but any feedback about changes to your code would be appreciated.

Attempting to write to a read-only array (one with
``arr.flags.writeable`` set to ``False``) used to raise either a
Expand All @@ -42,6 +39,11 @@ performance. Because of the nature of floating-point arithmetic, this
may subtly change some results, just as linking NumPy to a different
BLAS implementations such as MKL can.

If upgrading from 1.5, then generally in 1.6 and 1.7 there have been
substantial code added and some code paths altered, particularly in
the areas of type resolution and buffered iteration over universal
functions. This might have an impact on your code particularly if
you relied on accidental behavior in the past.

New features
============
Expand Down
7 changes: 5 additions & 2 deletions numpy/core/src/multiarray/mapping.c
Expand Up @@ -1023,8 +1023,10 @@ array_subscript(PyArrayObject *self, PyObject *op)
}

/* Boolean indexing special case */
/* The SIZE check might be overly cautious */
if (PyArray_Check(op) && (PyArray_TYPE((PyArrayObject *)op) == NPY_BOOL)
&& (PyArray_NDIM(self) == PyArray_NDIM((PyArrayObject *)op))) {
&& (PyArray_NDIM(self) == PyArray_NDIM((PyArrayObject *)op))
&& (PyArray_SIZE((PyArrayObject *)op) == PyArray_SIZE(self))) {
return (PyObject *)array_boolean_subscript(self,
(PyArrayObject *)op, NPY_CORDER);
}
Expand Down Expand Up @@ -1269,7 +1271,8 @@ array_ass_sub(PyArrayObject *self, PyObject *ind, PyObject *op)
/* Boolean indexing special case */
if (PyArray_Check(ind) &&
(PyArray_TYPE((PyArrayObject *)ind) == NPY_BOOL) &&
(PyArray_NDIM(self) == PyArray_NDIM((PyArrayObject *)ind))) {
(PyArray_NDIM(self) == PyArray_NDIM((PyArrayObject *)ind)) &&
(PyArray_SIZE(self) == PyArray_SIZE((PyArrayObject *)ind))) {
int retcode;
PyArrayObject *op_arr;
PyArray_Descr *dtype = NULL;
Expand Down
35 changes: 35 additions & 0 deletions numpy/core/tests/test_multiarray.py
Expand Up @@ -1058,6 +1058,41 @@ def test_tuple(self):
x[:,:,(0,)] = 2.0
assert_array_equal(x, array([[[2.0]]]))

def test_mask(self):
x = array([1,2,3,4])
m = array([0,1],bool)
assert_array_equal(x[m], array([2]))

def test_mask2(self):
x = array([[1,2,3,4],[5,6,7,8]])
m = array([0,1],bool)
m2 = array([[0,1],[1,0]], bool)
m3 = array([[0,1]], bool)
assert_array_equal(x[m], array([[5,6,7,8]]))
assert_array_equal(x[m2], array([2,5]))
assert_array_equal(x[m3], array([2]))

def test_assign_mask(self):
x = array([1,2,3,4])
m = array([0,1],bool)
x[m] = 5
assert_array_equal(x, array([1,5,3,4]))

def test_assign_mask(self):
xorig = array([[1,2,3,4],[5,6,7,8]])
m = array([0,1],bool)
m2 = array([[0,1],[1,0]],bool)
m3 = array([[0,1]], bool)
x = xorig.copy()
x[m] = 10
assert_array_equal(x, array([[1,2,3,4],[10,10,10,10]]))
x = xorig.copy()
x[m2] = 10
assert_array_equal(x, array([[1,10,3,4],[10,6,7,8]]))
x = xorig.copy()
x[m3] = 10
assert_array_equal(x, array([[1,10,3,4],[5,6,7,8]]))


class TestStringCompare(TestCase):
def test_string(self):
Expand Down

0 comments on commit db1701b

Please sign in to comment.