From db6f50b27f2f705bd7ace8420a7204ff50872296 Mon Sep 17 00:00:00 2001 From: mattip Date: Sun, 13 Jan 2019 21:22:46 +0200 Subject: DOC: doctest structured array introduction --- numpy/doc/structured_arrays.py | 106 ++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 48 deletions(-) (limited to 'numpy/doc/structured_arrays.py') diff --git a/numpy/doc/structured_arrays.py b/numpy/doc/structured_arrays.py index e92a06124..da3a74bd6 100644 --- a/numpy/doc/structured_arrays.py +++ b/numpy/doc/structured_arrays.py @@ -13,8 +13,8 @@ datatypes organized as a sequence of named :term:`fields `. For example, >>> x = np.array([('Rex', 9, 81.0), ('Fido', 3, 27.0)], ... dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')]) >>> x - array([('Rex', 9, 81.0), ('Fido', 3, 27.0)], - dtype=[('name', 'S10'), ('age', '>> x['age'] = 5 >>> x - array([('Rex', 5, 81.0), ('Fido', 5, 27.0)], - dtype=[('name', 'S10'), ('age', '>> np.dtype([('x', 'f4'), ('y', np.float32), ('z', 'f4', (2,2))]) - dtype=[('x', '>> np.dtype([('x', 'f4'), ('y', np.float32), ('z', 'f4', (2, 2))]) + dtype([('x', '>> np.dtype([('x', 'f4'),('', 'i4'),('z', 'i8')]) + >>> np.dtype([('x', 'f4'), ('', 'i4'), ('z', 'i8')]) dtype([('x', '>> np.dtype('i8,f4,S3') + >>> np.dtype('i8, f4, S3') dtype([('f0', '>> np.dtype('3int8, float32, (2,3)float64') - dtype([('f0', 'i1', 3), ('f1', '>> np.dtype('3int8, float32, (2, 3)float64') + dtype([('f0', 'i1', (3,)), ('f1', '>> np.dtype({'names': ['col1', 'col2'], 'formats': ['i4','f4']}) + >>> np.dtype({'names': ['col1', 'col2'], 'formats': ['i4', 'f4']}) dtype([('col1', '>> np.dtype({'names': ['col1', 'col2'], - ... 'formats': ['i4','f4'], + ... 'formats': ['i4', 'f4'], ... 'offsets': [0, 4], ... 'itemsize': 12}) dtype({'names':['col1','col2'], 'formats':['>> np.dtype=({'col1': ('i1',0), 'col2': ('f4',1)}) - dtype([(('col1'), 'i1'), (('col2'), '>f4')]) + >>> np.dtype({'col1': ('i1', 0), 'col2': ('f4', 1)}) + dtype([('col1', 'i1'), ('col2', '>> def print_offsets(d): ... print("offsets:", [d.fields[name][1] for name in d.names]) ... print("itemsize:", d.itemsize) - >>> print_offsets(np.dtype('u1,u1,i4,u1,i8,u2')) + >>> print_offsets(np.dtype('u1, u1, i4, u1, i8, u2')) offsets: [0, 1, 2, 6, 7, 15] itemsize: 17 @@ -215,7 +215,7 @@ in bytes for simple datatypes, see :c:member:`PyArray_Descr.alignment`. The structure will also have trailing padding added so that its itemsize is a multiple of the largest field's alignment. :: - >>> print_offsets(np.dtype('u1,u1,i4,u1,i8,u2', align=True)) + >>> print_offsets(np.dtype('u1, u1, i4, u1, i8, u2', align=True)) offsets: [0, 1, 4, 8, 16, 24] itemsize: 32 @@ -255,6 +255,7 @@ string, which will be the field's title and field name respectively. For example:: >>> np.dtype([(('my title', 'name'), 'f4')]) + dtype([(('my title', 'name'), '>> np.dtype({'name': ('i4', 0, 'my title')}) + dtype([(('my title', 'name'), '>> for name in d.names: ... print(d.fields[name][:2]) + (dtype('int64'), 0) + (dtype('float32'), 8) Union types ----------- @@ -305,8 +309,8 @@ in the array, and not a list or array as these will trigger numpy's broadcasting rules. The tuple's elements are assigned to the successive fields of the array, from left to right:: - >>> x = np.array([(1,2,3),(4,5,6)], dtype='i8,f4,f8') - >>> x[1] = (7,8,9) + >>> x = np.array([(1, 2, 3), (4, 5, 6)], dtype='i8, f4, f8') + >>> x[1] = (7, 8, 9) >>> x array([(1, 2., 3.), (7, 8., 9.)], dtype=[('f0', '>> x = np.zeros(2, dtype='i8,f4,?,S1') + >>> x = np.zeros(2, dtype='i8, f4, ?, S1') >>> x[:] = 3 >>> x - array([(3, 3.0, True, b'3'), (3, 3.0, True, b'3')], + array([(3, 3., True, b'3'), (3, 3., True, b'3')], dtype=[('f0', '>> x[:] = np.arange(2) >>> x - array([(0, 0.0, False, b'0'), (1, 1.0, True, b'1')], + array([(0, 0., False, b'0'), (1, 1., True, b'1')], dtype=[('f0', '>> onefield = np.zeros(2, dtype=[('A', 'i4')]) >>> nostruct = np.zeros(2, dtype='i4') >>> nostruct[:] = twofield + Traceback (most recent call last): + File "", line 1, in ValueError: Can't cast from structure to non-structure, except if the structure only has a single field. >>> nostruct[:] = onefield >>> nostruct @@ -355,7 +361,7 @@ included in any of the fields are unaffected. :: >>> b = np.ones(3, dtype=[('x', 'f4'), ('y', 'S3'), ('z', 'O')]) >>> b[:] = a >>> b - array([(0.0, b'0.0', b''), (0.0, b'0.0', b''), (0.0, b'0.0', b'')], + array([(0., b'0.0', b''), (0., b'0.0', b''), (0., b'0.0', b'')], dtype=[('x', '>> x = np.array([(1,2),(3,4)], dtype=[('foo', 'i8'), ('bar', 'f4')]) + >>> x = np.array([(1, 2), (3, 4)], dtype=[('foo', 'i8'), ('bar', 'f4')]) >>> x['foo'] array([1, 3]) >>> x['foo'] = 10 @@ -386,9 +392,9 @@ The resulting array is a view into the original array. It shares the same memory locations and writing to the view will modify the original array. :: >>> y = x['bar'] - >>> y[:] = 10 + >>> y[:] = 11 >>> x - array([(10, 5.), (10, 5.)], + array([(10, 11.), (10, 11.)], dtype=[('foo', '>> x = np.zeros((2,2), dtype=[('a', np.int32), ('b', np.float64, (3,3))]) + >>> x = np.zeros((2, 2), dtype=[('a', np.int32), ('b', np.float64, (3, 3))]) >>> x['a'].shape (2, 2) >>> x['b'].shape @@ -438,8 +444,9 @@ same offsets as in the original array, and unindexed fields are merely missing. code which depends on the data having a "packed" layout. For instance code such as:: - >>> a = np.zeros(3, dtype=[('a', 'i4'), ('b', 'i4'), ('c', 'f4')]) - >>> a[['a','c']].view('i8') # Fails in Numpy 1.16 + >>> a[['a', 'c']].view('i8') # Fails in Numpy 1.16 + Traceback (most recent call last): + File "", line 1, in ValueError: When changing to a smaller dtype, its size must be a divisor of the size of original dtype will need to be changed. This code has raised a ``FutureWarning`` since @@ -459,7 +466,8 @@ same offsets as in the original array, and unindexed fields are merely missing. used to reproduce the old behavior, as it will return a packed copy of the structured array. The code above, for example, can be replaced with: - >>> repack_fields(a[['a','c']]).view('i8') # supported in 1.16 + >>> from numpy.lib.recfunctions import repack_fields + >>> repack_fields(a[['a', 'c']]).view('i8') # supported in 1.16 array([0, 0, 0]) Furthermore, numpy now provides a new function @@ -470,12 +478,14 @@ same offsets as in the original array, and unindexed fields are merely missing. account padding, often avoids a copy, and also casts the datatypes as needed, unlike the view. Code such as: - >>> a = np.zeros(3, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) - >>> a[['x', 'z']].view('f4') + >>> b = np.zeros(3, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) + >>> b[['x', 'z']].view('f4') + array([0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32) can be made safer by replacing with: - >>> structured_to_unstructured(a[['x', 'z']]) + >>> from numpy.lib.recfunctions import structured_to_unstructured + >>> structured_to_unstructured(b[['x', 'z']]) array([0, 0, 0]) @@ -483,8 +493,8 @@ Assignment to an array with a multi-field index modifies the original array:: >>> a[['a', 'c']] = (2, 3) >>> a - array([(2, 0, 3.0), (2, 0, 3.0), (2, 0, 3.0)], - dtype=[('a', '>> x = np.array([(1, 2., 3.)], dtype='i,f,f') + >>> x = np.array([(1, 2., 3.)], dtype='i, f, f') >>> scalar = x[0] >>> scalar (1, 2., 3.) >>> type(scalar) - numpy.void + Unlike other numpy scalars, structured scalars are mutable and act like views into the original array, such that modifying the scalar will modify the original array. Structured scalars also support access and assignment by field name:: - >>> x = np.array([(1,2),(3,4)], dtype=[('foo', 'i8'), ('bar', 'f4')]) + >>> x = np.array([(1, 2), (3, 4)], dtype=[('foo', 'i8'), ('bar', 'f4')]) >>> s = x[0] >>> s['bar'] = 100 >>> x @@ -519,7 +529,7 @@ name:: Similarly to tuples, structured scalars can also be indexed with an integer:: - >>> scalar = np.array([(1, 2., 3.)], dtype='i,f,f')[0] + >>> scalar = np.array([(1, 2., 3.)], dtype='i, f, f')[0] >>> scalar[0] 1 >>> scalar[1] = 4 @@ -530,7 +540,7 @@ numpy's integer types. Structured scalars may be converted to a tuple by calling :func:`ndarray.item`:: >>> scalar.item(), type(scalar.item()) - ((1, 2.0, 3.0), tuple) + ((1, 4.0, 3.0), ) Viewing Structured Arrays Containing Objects -------------------------------------------- @@ -574,24 +584,24 @@ structured scalars obtained from the array. The simplest way to create a record array is with :func:`numpy.rec.array`:: - >>> recordarr = np.rec.array([(1,2.,'Hello'),(2,3.,"World")], + >>> recordarr = np.rec.array([(1, 2., 'Hello'), (2, 3., "World")], ... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')]) >>> recordarr.bar array([ 2., 3.], dtype=float32) >>> recordarr[1:2] - rec.array([(2, 3.0, 'World')], + rec.array([(2, 3., b'World')], dtype=[('foo', '>> recordarr[1:2].foo array([2], dtype=int32) >>> recordarr.foo[1:2] array([2], dtype=int32) >>> recordarr[1].baz - 'World' + b'World' :func:`numpy.rec.array` can convert a wide variety of arguments into record arrays, including structured arrays:: - >>> arr = array([(1,2.,'Hello'),(2,3.,"World")], + >>> arr = np.array([(1, 2., 'Hello'), (2, 3., "World")], ... dtype=[('foo', 'i4'), ('bar', 'f4'), ('baz', 'S10')]) >>> recordarr = np.rec.array(arr) @@ -602,9 +612,9 @@ creating record arrays, see :ref:`record array creation routines A record array representation of a structured array can be obtained using the appropriate :ref:`view`:: - >>> arr = np.array([(1,2.,'Hello'),(2,3.,"World")], + >>> arr = np.array([(1, 2., 'Hello'), (2, 3., "World")], ... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'a10')]) - >>> recordarr = arr.view(dtype=dtype((np.record, arr.dtype)), + >>> recordarr = arr.view(dtype=np.dtype((np.record, arr.dtype)), ... type=np.recarray) For convenience, viewing an ndarray as type :class:`np.recarray` will @@ -624,12 +634,12 @@ recordarr was not a structured type:: Record array fields accessed by index or by attribute are returned as a record array if the field has a structured type but as a plain ndarray otherwise. :: - >>> recordarr = np.rec.array([('Hello', (1,2)),("World", (3,4))], + >>> recordarr = np.rec.array([('Hello', (1, 2)), ("World", (3, 4))], ... dtype=[('foo', 'S6'),('bar', [('A', int), ('B', int)])]) >>> type(recordarr.foo) - + >>> type(recordarr.bar) - + Note that if a field has the same name as an ndarray attribute, the ndarray attribute takes precedence. Such fields will be inaccessible by attribute but -- cgit v1.2.1