diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2015-06-19 17:31:35 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2015-06-21 12:43:06 -0600 |
commit | f6861923209df65d9c4253368061072eda67ea77 (patch) | |
tree | 4f7f1799456522e84728a5c9f08061f59d5ac555 | |
parent | 5b8ec8915ef5e2fa58824411be4ea1e17736d08a (diff) | |
download | numpy-f6861923209df65d9c4253368061072eda67ea77.tar.gz |
DEP,MAINT: Raise IndexError if axis != 0 when concatenating 1-D arrays.
This was deprecated in NumPy 1.7 with a warning that it would raise
an error in the future. Tests for the new error are added and the
test that allowed that special case is removed.
-rw-r--r-- | doc/release/1.10.0-notes.rst | 8 | ||||
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.c | 10 | ||||
-rw-r--r-- | numpy/core/tests/test_shape_base.py | 174 |
3 files changed, 98 insertions, 94 deletions
diff --git a/doc/release/1.10.0-notes.rst b/doc/release/1.10.0-notes.rst index ed33cc9e3..d3b99cf76 100644 --- a/doc/release/1.10.0-notes.rst +++ b/doc/release/1.10.0-notes.rst @@ -52,6 +52,11 @@ relaxed stride checking ~~~~~~~~~~~~~~~~~~~~~~~ NPY_RELAXED_STRIDE_CHECKING is now true by default. +Concatenation of 1d arrays along any but ``axis=0`` raises ``IndexError`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Using axis != 0 has raised a DeprecationWarning since NumPy 1.7, it now +raises an error. + *np.ravel*, *np.diagonal* and *np.diag* now preserve subtypes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There was inconsistent behavior between *x.ravel()* and *np.ravel(x)*, as @@ -76,6 +81,9 @@ which now returns a view in all cases. The dtype structure (PyArray_Descr) has a new member at the end to cache its hash value. This shouldn't affect any well-written applications. +The change to the concatenation function DeprecationWarning also affects +PyArray_ConcatenateArrays, + recarray field return types ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Previously the returned types for recarray fields accessed by attribute and by diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index f8656d8c3..3fe8611d4 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -347,16 +347,6 @@ PyArray_ConcatenateArrays(int narrays, PyArrayObject **arrays, int axis) axis += ndim; } - if (ndim == 1 && axis != 0) { - static const char msg[] = "axis != 0 for ndim == 1; " - "this will raise an error in " - "future versions of numpy"; - if (DEPRECATE(msg) < 0) { - return NULL; - } - axis = 0; - } - if (axis < 0 || axis >= ndim) { PyErr_Format(PyExc_IndexError, "axis %d out of bounds [0, %d)", orig_axis, ndim); diff --git a/numpy/core/tests/test_shape_base.py b/numpy/core/tests/test_shape_base.py index c387bc616..52001ff37 100644 --- a/numpy/core/tests/test_shape_base.py +++ b/numpy/core/tests/test_shape_base.py @@ -173,90 +173,96 @@ class TestVstack(TestCase): assert_array_equal(res, desired) -def test_concatenate_axis_None(): - a = np.arange(4, dtype=np.float64).reshape((2, 2)) - b = list(range(3)) - c = ['x'] - r = np.concatenate((a, a), axis=None) - assert_equal(r.dtype, a.dtype) - assert_equal(r.ndim, 1) - r = np.concatenate((a, b), axis=None) - assert_equal(r.size, a.size + len(b)) - assert_equal(r.dtype, a.dtype) - r = np.concatenate((a, b, c), axis=None) - d = array(['0.0', '1.0', '2.0', '3.0', - '0', '1', '2', 'x']) - assert_array_equal(r, d) - - -def test_large_concatenate_axis_None(): - # When no axis is given, concatenate uses flattened versions. - # This also had a bug with many arrays (see gh-5979). - x = np.arange(1, 100) - r = np.concatenate(x, None) - assert_array_equal(x, r) - - # This should probably be deprecated: - r = np.concatenate(x, 100) # axis is >= MAXDIMS - assert_array_equal(x, r) - - -def test_concatenate(): - # Test concatenate function - # No arrays raise ValueError - assert_raises(ValueError, concatenate, ()) - # Scalars cannot be concatenated - assert_raises(ValueError, concatenate, (0,)) - assert_raises(ValueError, concatenate, (array(0),)) - # One sequence returns unmodified (but as array) - r4 = list(range(4)) - assert_array_equal(concatenate((r4,)), r4) - # Any sequence - assert_array_equal(concatenate((tuple(r4),)), r4) - assert_array_equal(concatenate((array(r4),)), r4) - # 1D default concatenation - r3 = list(range(3)) - assert_array_equal(concatenate((r4, r3)), r4 + r3) - # Mixed sequence types - assert_array_equal(concatenate((tuple(r4), r3)), r4 + r3) - assert_array_equal(concatenate((array(r4), r3)), r4 + r3) - # Explicit axis specification - assert_array_equal(concatenate((r4, r3), 0), r4 + r3) - # Including negative - assert_array_equal(concatenate((r4, r3), -1), r4 + r3) - # 2D - a23 = array([[10, 11, 12], [13, 14, 15]]) - a13 = array([[0, 1, 2]]) - res = array([[10, 11, 12], [13, 14, 15], [0, 1, 2]]) - assert_array_equal(concatenate((a23, a13)), res) - assert_array_equal(concatenate((a23, a13), 0), res) - assert_array_equal(concatenate((a23.T, a13.T), 1), res.T) - assert_array_equal(concatenate((a23.T, a13.T), -1), res.T) - # Arrays much match shape - assert_raises(ValueError, concatenate, (a23.T, a13.T), 0) - # 3D - res = arange(2 * 3 * 7).reshape((2, 3, 7)) - a0 = res[..., :4] - a1 = res[..., 4:6] - a2 = res[..., 6:] - assert_array_equal(concatenate((a0, a1, a2), 2), res) - assert_array_equal(concatenate((a0, a1, a2), -1), res) - assert_array_equal(concatenate((a0.T, a1.T, a2.T), 0), res.T) - - -def test_concatenate_sloppy0(): - # Versions of numpy < 1.7.0 ignored axis argument value for 1D arrays. We - # allow this for now, but in due course we will raise an error - r4 = list(range(4)) - r3 = list(range(3)) - assert_array_equal(concatenate((r4, r3), 0), r4 + r3) - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - assert_array_equal(concatenate((r4, r3), -10), r4 + r3) - assert_array_equal(concatenate((r4, r3), 10), r4 + r3) - # Confirm DeprecationWarning raised - warnings.simplefilter('error', DeprecationWarning) - assert_raises(DeprecationWarning, concatenate, (r4, r3), 10) +class TestConcatenate(TestCase): + def test_exceptions(self): + # test axis must be in bounds + for ndim in [1, 2, 3]: + a = np.ones((1,)*ndim) + np.concatenate((a, a), axis=0) # OK + assert_raises(IndexError, np.concatenate, (a, a), axis=ndim) + assert_raises(IndexError, np.concatenate, (a, a), axis=-(ndim + 1)) + + # Scalars cannot be concatenated + assert_raises(ValueError, concatenate, (0,)) + assert_raises(ValueError, concatenate, (np.array(0),)) + + # test shapes must match except for concatenation axis + a = np.ones((1, 2, 3)) + b = np.ones((2, 2, 3)) + axis = list(range(3)) + for i in range(3): + np.concatenate((a, b), axis=axis[0]) # OK + assert_raises(ValueError, np.concatenate, (a, b), axis=axis[1]) + assert_raises(ValueError, np.concatenate, (a, b), axis=axis[2]) + a = np.rollaxis(a, -1) + b = np.rollaxis(b, -1) + axis.append(axis.pop(0)) + + # No arrays to concatenate raises ValueError + assert_raises(ValueError, concatenate, ()) + + def test_concatenate_axis_None(self): + a = np.arange(4, dtype=np.float64).reshape((2, 2)) + b = list(range(3)) + c = ['x'] + r = np.concatenate((a, a), axis=None) + assert_equal(r.dtype, a.dtype) + assert_equal(r.ndim, 1) + r = np.concatenate((a, b), axis=None) + assert_equal(r.size, a.size + len(b)) + assert_equal(r.dtype, a.dtype) + r = np.concatenate((a, b, c), axis=None) + d = array(['0.0', '1.0', '2.0', '3.0', + '0', '1', '2', 'x']) + assert_array_equal(r, d) + + def test_large_concatenate_axis_None(self): + # When no axis is given, concatenate uses flattened versions. + # This also had a bug with many arrays (see gh-5979). + x = np.arange(1, 100) + r = np.concatenate(x, None) + assert_array_equal(x, r) + + # This should probably be deprecated: + r = np.concatenate(x, 100) # axis is >= MAXDIMS + assert_array_equal(x, r) + + def test_concatenate(self): + # Test concatenate function + # One sequence returns unmodified (but as array) + r4 = list(range(4)) + assert_array_equal(concatenate((r4,)), r4) + # Any sequence + assert_array_equal(concatenate((tuple(r4),)), r4) + assert_array_equal(concatenate((array(r4),)), r4) + # 1D default concatenation + r3 = list(range(3)) + assert_array_equal(concatenate((r4, r3)), r4 + r3) + # Mixed sequence types + assert_array_equal(concatenate((tuple(r4), r3)), r4 + r3) + assert_array_equal(concatenate((array(r4), r3)), r4 + r3) + # Explicit axis specification + assert_array_equal(concatenate((r4, r3), 0), r4 + r3) + # Including negative + assert_array_equal(concatenate((r4, r3), -1), r4 + r3) + # 2D + a23 = array([[10, 11, 12], [13, 14, 15]]) + a13 = array([[0, 1, 2]]) + res = array([[10, 11, 12], [13, 14, 15], [0, 1, 2]]) + assert_array_equal(concatenate((a23, a13)), res) + assert_array_equal(concatenate((a23, a13), 0), res) + assert_array_equal(concatenate((a23.T, a13.T), 1), res.T) + assert_array_equal(concatenate((a23.T, a13.T), -1), res.T) + # Arrays much match shape + assert_raises(ValueError, concatenate, (a23.T, a13.T), 0) + # 3D + res = arange(2 * 3 * 7).reshape((2, 3, 7)) + a0 = res[..., :4] + a1 = res[..., 4:6] + a2 = res[..., 6:] + assert_array_equal(concatenate((a0, a1, a2), 2), res) + assert_array_equal(concatenate((a0, a1, a2), -1), res) + assert_array_equal(concatenate((a0.T, a1.T, a2.T), 0), res.T) def test_stack(): |