summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2017-02-24 17:07:31 +0000
committerEric Wieser <wieser.eric@gmail.com>2017-02-25 13:57:13 +0000
commit38ce8097749ad69494926036250ed5b2de66184c (patch)
tree17e176067c11081da0843fc78c9920ccb9281130
parent48783e5ceb7f60c33db81ab72e5024f42b220990 (diff)
downloadnumpy-38ce8097749ad69494926036250ed5b2de66184c.tar.gz
ENH: add a .ndim property to dype objects
This complements the .shape property
-rw-r--r--doc/release/1.13.0-notes.rst5
-rw-r--r--numpy/add_newdocs.py9
-rw-r--r--numpy/core/src/multiarray/descriptor.c22
-rw-r--r--numpy/core/tests/test_dtype.py17
4 files changed, 53 insertions, 0 deletions
diff --git a/doc/release/1.13.0-notes.rst b/doc/release/1.13.0-notes.rst
index ae3c64fdd..03e5f955a 100644
--- a/doc/release/1.13.0-notes.rst
+++ b/doc/release/1.13.0-notes.rst
@@ -159,6 +159,11 @@ to `apply_along_axis`. Now, it can return an array of any dimensionality
(including 0D), and the shape of this array replaces the axis of the array
being iterated over.
+``.ndim`` property added to ``dtype`` to complement ``.shape``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+For consistency with ``ndarray`` and ``broadcast``, ``d.ndim`` is a shorthand
+for ``len(d.shape)``.
+
Changes
=======
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py
index 3916d1304..cf4af9f84 100644
--- a/numpy/add_newdocs.py
+++ b/numpy/add_newdocs.py
@@ -6355,6 +6355,15 @@ add_newdoc('numpy.core.multiarray', 'dtype', ('shape',
"""))
+add_newdoc('numpy.core.multiarray', 'dtype', ('ndim',
+ """
+ Number of dimensions of the sub-array if this data type describes a
+ sub-array, and ``0`` otherwise.
+
+ .. versionadded:: 1.13.0
+
+ """))
+
add_newdoc('numpy.core.multiarray', 'dtype', ('str',
"""The array-protocol typestring of this data-type object."""))
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c
index 6c2186f9c..86da751ba 100644
--- a/numpy/core/src/multiarray/descriptor.c
+++ b/numpy/core/src/multiarray/descriptor.c
@@ -1950,6 +1950,25 @@ arraydescr_shape_get(PyArray_Descr *self)
return Py_BuildValue("(O)", self->subarray->shape);
}
+static PyObject *
+arraydescr_ndim_get(PyArray_Descr *self)
+{
+ if (!PyDataType_HASSUBARRAY(self)) {
+ return PyInt_FromLong(0);
+ }
+ /*TODO
+ * self->subarray->shape should always be a tuple,
+ * so this check should be unnecessary
+ */
+ if (PyTuple_Check(self->subarray->shape)) {
+ Py_ssize_t ndim = PyTuple_Size(self->subarray->shape);
+ return PyInt_FromLong(ndim);
+ }
+ /* consistent with arraydescr_shape_get */
+ return PyInt_FromLong(1);
+}
+
+
NPY_NO_EXPORT PyObject *
arraydescr_protocol_descr_get(PyArray_Descr *self)
{
@@ -2208,6 +2227,9 @@ static PyGetSetDef arraydescr_getsets[] = {
{"shape",
(getter)arraydescr_shape_get,
NULL, NULL, NULL},
+ {"ndim",
+ (getter)arraydescr_ndim_get,
+ NULL, NULL, NULL},
{"isbuiltin",
(getter)arraydescr_isbuiltin_get,
NULL, NULL, NULL},
diff --git a/numpy/core/tests/test_dtype.py b/numpy/core/tests/test_dtype.py
index c0143aae3..f8e9b899d 100644
--- a/numpy/core/tests/test_dtype.py
+++ b/numpy/core/tests/test_dtype.py
@@ -376,6 +376,23 @@ class TestSubarray(TestCase):
assert_(isinstance(dt['a'].shape, tuple))
assert_(isinstance(dt['a'].shape[0], int))
+ def test_shape_matches_ndim(self):
+ dt = np.dtype([('a', 'f4', ())])
+ assert_equal(dt['a'].shape, ())
+ assert_equal(dt['a'].ndim, 0)
+
+ dt = np.dtype([('a', 'f4')])
+ assert_equal(dt['a'].shape, ())
+ assert_equal(dt['a'].ndim, 0)
+
+ dt = np.dtype([('a', 'f4', 4)])
+ assert_equal(dt['a'].shape, (4,))
+ assert_equal(dt['a'].ndim, 1)
+
+ dt = np.dtype([('a', 'f4', (1, 2, 3))])
+ assert_equal(dt['a'].shape, (1, 2, 3))
+ assert_equal(dt['a'].ndim, 3)
+
def test_shape_invalid(self):
# Check that the shape is valid.
max_int = np.iinfo(np.intc).max