summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Haldane <allan.haldane@gmail.com>2015-01-16 23:53:41 -0500
committerAllan Haldane <allan.haldane@gmail.com>2015-01-22 17:36:43 -0500
commit1bd0b4e8f176cd80e81b5f50832db5f8ba1ee1e9 (patch)
treefce876400e049c7927cfe4b62ee4d1ca00a8ed7b
parentb69035e8ea28bd759b929822aaba544d3c5f8c30 (diff)
downloadnumpy-1bd0b4e8f176cd80e81b5f50832db5f8ba1ee1e9.tar.gz
DOC: improve record/structured array nomenclature & guide
This update adds a section better describing record arrays in the user guide (numpy/doc/structured_arrays.py). It also corrects nomenclature, such that "structured array" refers to ndarrays with structured dtype, "record array" refers to modified ndarrays as created by np.rec.array, and "recarray" refers to ndarrays viewed as np.recarray. See the note at the end of the structured array user guide.
-rw-r--r--doc/source/reference/arrays.classes.rst2
-rw-r--r--doc/source/reference/arrays.dtypes.rst30
-rw-r--r--doc/source/reference/arrays.indexing.rst18
-rw-r--r--doc/source/reference/arrays.interface.rst11
-rw-r--r--doc/source/reference/arrays.ndarray.rst2
-rw-r--r--doc/source/reference/arrays.scalars.rst16
-rw-r--r--doc/source/reference/c-api.array.rst14
-rw-r--r--doc/source/reference/internals.code-explanations.rst6
-rw-r--r--doc/source/user/basics.rec.rst6
-rw-r--r--numpy/add_newdocs.py9
-rw-r--r--numpy/core/records.py8
-rw-r--r--numpy/core/src/multiarray/arrayobject.c2
-rw-r--r--numpy/doc/creation.py2
-rw-r--r--numpy/doc/glossary.py12
-rw-r--r--numpy/doc/structured_arrays.py129
-rw-r--r--numpy/lib/npyio.py4
16 files changed, 179 insertions, 92 deletions
diff --git a/doc/source/reference/arrays.classes.rst b/doc/source/reference/arrays.classes.rst
index e77dfc31e..caaf3a73b 100644
--- a/doc/source/reference/arrays.classes.rst
+++ b/doc/source/reference/arrays.classes.rst
@@ -337,7 +337,7 @@ Record arrays (:mod:`numpy.rec`)
:ref:`arrays.dtypes`.
Numpy provides the :class:`recarray` class which allows accessing the
-fields of a record/structured array as attributes, and a corresponding
+fields of a structured array as attributes, and a corresponding
scalar data type object :class:`record`.
.. currentmodule:: numpy
diff --git a/doc/source/reference/arrays.dtypes.rst b/doc/source/reference/arrays.dtypes.rst
index 797f1f6f8..a43c23218 100644
--- a/doc/source/reference/arrays.dtypes.rst
+++ b/doc/source/reference/arrays.dtypes.rst
@@ -14,12 +14,12 @@ following aspects of the data:
1. Type of the data (integer, float, Python object, etc.)
2. Size of the data (how many bytes is in *e.g.* the integer)
3. Byte order of the data (:term:`little-endian` or :term:`big-endian`)
-4. If the data type is a :term:`record`, an aggregate of other
+4. If the data type is :term:`structured`, an aggregate of other
data types, (*e.g.*, describing an array item consisting of
an integer and a float),
- 1. what are the names of the ":term:`fields <field>`" of the record,
- by which they can be :ref:`accessed <arrays.indexing.rec>`,
+ 1. what are the names of the ":term:`fields <field>`" of the structure,
+ by which they can be :ref:`accessed <arrays.indexing.fields>`,
2. what is the data-type of each :term:`field`, and
3. which part of the memory block each field takes.
@@ -40,15 +40,14 @@ needed in Numpy.
.. index::
pair: dtype; field
- pair: dtype; record
-Struct data types are formed by creating a data type whose
+Structured data types are formed by creating a data type whose
:term:`fields` contain other data types. Each field has a name by
-which it can be :ref:`accessed <arrays.indexing.rec>`. The parent data
+which it can be :ref:`accessed <arrays.indexing.fields>`. The parent data
type should be of sufficient size to contain all its fields; the
parent is nearly always based on the :class:`void` type which allows
-an arbitrary item size. Struct data types may also contain nested struct
-sub-array data types in their fields.
+an arbitrary item size. Structured data types may also contain nested
+structured sub-array data types in their fields.
.. index::
pair: dtype; sub-array
@@ -60,7 +59,7 @@ fixed size.
If an array is created using a data-type describing a sub-array,
the dimensions of the sub-array are appended to the shape
of the array when the array is created. Sub-arrays in a field of a
-record behave differently, see :ref:`arrays.indexing.rec`.
+structured type behave differently, see :ref:`arrays.indexing.fields`.
Sub-arrays always have a C-contiguous memory layout.
@@ -83,7 +82,7 @@ Sub-arrays always have a C-contiguous memory layout.
.. admonition:: Example
- A record data type containing a 16-character string (in field 'name')
+ A structured data type containing a 16-character string (in field 'name')
and a sub-array of two 64-bit floating-point number (in field 'grades'):
>>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
@@ -246,8 +245,8 @@ Array-protocol type strings (see :ref:`arrays.interface`)
String with comma-separated fields
- Numarray introduced a short-hand notation for specifying the format
- of a record as a comma-separated string of basic formats.
+ A short-hand notation for specifying the format of a structured data type is
+ a comma-separated string of basic formats.
A basic format in this context is an optional shape specifier
followed by an array-protocol type string. Parenthesis are required
@@ -315,7 +314,7 @@ Type strings
>>> dt = np.dtype((np.int32, (2,2))) # 2 x 2 integer sub-array
>>> dt = np.dtype(('S10', 1)) # 10-character string
- >>> dt = np.dtype(('i4, (2,3)f8, f4', (2,3))) # 2 x 3 record sub-array
+ >>> dt = np.dtype(('i4, (2,3)f8, f4', (2,3))) # 2 x 3 structured sub-array
.. index::
triple: dtype; construction; from list
@@ -432,7 +431,8 @@ Type strings
Both arguments must be convertible to data-type objects in this
case. The *base_dtype* is the data-type object that the new
data-type builds on. This is how you could assign named fields to
- any built-in data-type object.
+ any built-in data-type object, as done in
+ :ref:`record arrays <arrays.classes.rec>`.
.. admonition:: Example
@@ -486,7 +486,7 @@ Endianness of this data:
dtype.byteorder
-Information about sub-data-types in a :term:`record`:
+Information about sub-data-types in a :term:`structured` data type:
.. autosummary::
:toctree: generated/
diff --git a/doc/source/reference/arrays.indexing.rst b/doc/source/reference/arrays.indexing.rst
index ef0180e0f..2eb07c4e0 100644
--- a/doc/source/reference/arrays.indexing.rst
+++ b/doc/source/reference/arrays.indexing.rst
@@ -11,7 +11,7 @@ Indexing
:class:`ndarrays <ndarray>` can be indexed using the standard Python
``x[obj]`` syntax, where *x* is the array and *obj* the selection.
-There are three kinds of indexing available: record access, basic
+There are three kinds of indexing available: field access, basic
slicing, advanced indexing. Which one occurs depends on *obj*.
.. note::
@@ -489,25 +489,25 @@ indexing (in no particular order):
view on the data. This *must* be done if the subclasses ``__getitem__`` does
not return views.
-.. _arrays.indexing.rec:
+.. _arrays.indexing.fields:
-Record Access
+Field Access
-------------
.. seealso:: :ref:`arrays.dtypes`, :ref:`arrays.scalars`
-If the :class:`ndarray` object is a record array, *i.e.* its data type
-is a :term:`record` data type, the :term:`fields <field>` of the array
-can be accessed by indexing the array with strings, dictionary-like.
+If the :class:`ndarray` object is a structured array the :term:`fields <field>`
+of the array can be accessed by indexing the array with strings,
+dictionary-like.
Indexing ``x['field-name']`` returns a new :term:`view` to the array,
which is of the same shape as *x* (except when the field is a
sub-array) but of data type ``x.dtype['field-name']`` and contains
-only the part of the data in the specified field. Also record array
-scalars can be "indexed" this way.
+only the part of the data in the specified field. Also
+:ref:`record array <arrays.classes.rec>` scalars can be "indexed" this way.
-Indexing into a record array can also be done with a list of field names,
+Indexing into a structured array can also be done with a list of field names,
*e.g.* ``x[['field-name1','field-name2']]``. Currently this returns a new
array containing a copy of the values in the fields specified in the list.
As of NumPy 1.7, returning a copy is being deprecated in favor of returning
diff --git a/doc/source/reference/arrays.interface.rst b/doc/source/reference/arrays.interface.rst
index 16abe5ce1..50595c2d8 100644
--- a/doc/source/reference/arrays.interface.rst
+++ b/doc/source/reference/arrays.interface.rst
@@ -103,19 +103,19 @@ This approach to the interface consists of the object having an
not a requirement. The only requirement is that the number of
bytes represented in the *typestr* key is the same as the total
number of bytes represented here. The idea is to support
- descriptions of C-like structs (records) that make up array
+ descriptions of C-like structs that make up array
elements. The elements of each tuple in the list are
1. A string providing a name associated with this portion of
- the record. This could also be a tuple of ``('full name',
+ the datatype. This could also be a tuple of ``('full name',
'basic_name')`` where basic name would be a valid Python
variable name representing the full name of the field.
2. Either a basic-type description string as in *typestr* or
- another list (for nested records)
+ another list (for nested structured types)
3. An optional shape tuple providing how many times this part
- of the record should be repeated. No repeats are assumed
+ of the structure should be repeated. No repeats are assumed
if this is not given. Very complicated structures can be
described using this generic interface. Notice, however,
that each element of the array is still of the same
@@ -301,7 +301,8 @@ more information which may be important for various applications::
typestr == '|V16'
descr == [('ival','>i4'),('','|V4'),('dval','>f8')]
-It should be clear that any record type could be described using this interface.
+It should be clear that any structured type could be described using this
+interface.
Differences with Array interface (Version 2)
============================================
diff --git a/doc/source/reference/arrays.ndarray.rst b/doc/source/reference/arrays.ndarray.rst
index e9c0a6d87..c8d834d1c 100644
--- a/doc/source/reference/arrays.ndarray.rst
+++ b/doc/source/reference/arrays.ndarray.rst
@@ -82,7 +82,7 @@ Indexing arrays
Arrays can be indexed using an extended Python slicing syntax,
``array[selection]``. Similar syntax is also used for accessing
-fields in a :ref:`record array <arrays.dtypes>`.
+fields in a :ref:`structured array <arrays.dtypes.field>`.
.. seealso:: :ref:`Array Indexing <arrays.indexing>`.
diff --git a/doc/source/reference/arrays.scalars.rst b/doc/source/reference/arrays.scalars.rst
index f229efb07..652fa62e1 100644
--- a/doc/source/reference/arrays.scalars.rst
+++ b/doc/source/reference/arrays.scalars.rst
@@ -250,7 +250,7 @@ array scalar,
- ``x[()]`` returns a 0-dimensional :class:`ndarray`
- ``x['field-name']`` returns the array scalar in the field *field-name*.
- (*x* can have fields, for example, when it corresponds to a record data type.)
+ (*x* can have fields, for example, when it corresponds to a structured data type.)
Methods
=======
@@ -282,10 +282,10 @@ Defining new types
==================
There are two ways to effectively define a new array scalar type
-(apart from composing record :ref:`dtypes <arrays.dtypes>` from the built-in
-scalar types): One way is to simply subclass the :class:`ndarray` and
-overwrite the methods of interest. This will work to a degree, but
-internally certain behaviors are fixed by the data type of the array.
-To fully customize the data type of an array you need to define a new
-data-type, and register it with NumPy. Such new types can only be
-defined in C, using the :ref:`Numpy C-API <c-api>`.
+(apart from composing structured types :ref:`dtypes <arrays.dtypes>` from
+the built-in scalar types): One way is to simply subclass the
+:class:`ndarray` and overwrite the methods of interest. This will work to
+a degree, but internally certain behaviors are fixed by the data type of
+the array. To fully customize the data type of an array you need to
+define a new data-type, and register it with NumPy. Such new types can only
+be defined in C, using the :ref:`Numpy C-API <c-api>`.
diff --git a/doc/source/reference/c-api.array.rst b/doc/source/reference/c-api.array.rst
index 08eba243e..9b8cc04b6 100644
--- a/doc/source/reference/c-api.array.rst
+++ b/doc/source/reference/c-api.array.rst
@@ -1240,9 +1240,9 @@ Special functions for NPY_OBJECT
A function to INCREF all the objects at the location *ptr*
according to the data-type *dtype*. If *ptr* is the start of a
- record with an object at any offset, then this will (recursively)
+ structured type with an object at any offset, then this will (recursively)
increment the reference count of all object-like items in the
- record.
+ structured type.
.. cfunction:: int PyArray_XDECREF(PyArrayObject* op)
@@ -1253,7 +1253,7 @@ Special functions for NPY_OBJECT
.. cfunction:: void PyArray_Item_XDECREF(char* ptr, PyArray_Descr* dtype)
- A function to XDECREF all the object-like items at the loacation
+ A function to XDECREF all the object-like items at the location
*ptr* as recorded in the data-type, *dtype*. This works
recursively so that if ``dtype`` itself has fields with data-types
that contain object-like items, all the object-like fields will be
@@ -1540,7 +1540,7 @@ Conversion
itemsize of the new array type must be less than *self*
->descr->elsize or an error is raised. The same shape and strides
as the original array are used. Therefore, this function has the
- effect of returning a field from a record array. But, it can also
+ effect of returning a field from a structured array. But, it can also
be used to select specific bytes or groups of bytes from any array
type.
@@ -1786,7 +1786,7 @@ Item selection and manipulation
->descr is a data-type with fields defined, then
self->descr->names is used to determine the sort order. A
comparison where the first field is equal will use the second
- field and so on. To alter the sort order of a record array, create
+ field and so on. To alter the sort order of a structured array, create
a new data-type with a different order of names and construct a
view of the array with that new data-type.
@@ -1805,7 +1805,7 @@ Item selection and manipulation
to understand the order the *sort_keys* must be in (reversed from
the order you would use when comparing two elements).
- If these arrays are all collected in a record array, then
+ If these arrays are all collected in a structured array, then
:cfunc:`PyArray_Sort` (...) can also be used to sort the array
directly.
@@ -1838,7 +1838,7 @@ Item selection and manipulation
If *self*->descr is a data-type with fields defined, then
self->descr->names is used to determine the sort order. A comparison where
the first field is equal will use the second field and so on. To alter the
- sort order of a record array, create a new data-type with a different
+ sort order of a structured array, create a new data-type with a different
order of names and construct a view of the array with that new data-type.
Returns zero on success and -1 on failure.
diff --git a/doc/source/reference/internals.code-explanations.rst b/doc/source/reference/internals.code-explanations.rst
index 580661cb3..f01300e25 100644
--- a/doc/source/reference/internals.code-explanations.rst
+++ b/doc/source/reference/internals.code-explanations.rst
@@ -74,9 +74,9 @@ optimizations that by-pass this mechanism, but the point of the data-
type abstraction is to allow new data-types to be added.
One of the built-in data-types, the void data-type allows for
-arbitrary records containing 1 or more fields as elements of the
+arbitrary structured types containing 1 or more fields as elements of the
array. A field is simply another data-type object along with an offset
-into the current record. In order to support arbitrarily nested
+into the current structured type. In order to support arbitrarily nested
fields, several recursive implementations of data-type access are
implemented for the void type. A common idiom is to cycle through the
elements of the dictionary and perform a specific operation based on
@@ -184,7 +184,7 @@ The array scalars also offer the same methods and attributes as arrays
with the intent that the same code can be used to support arbitrary
dimensions (including 0-dimensions). The array scalars are read-only
(immutable) with the exception of the void scalar which can also be
-written to so that record-array field setting works more naturally
+written to so that structured array field setting works more naturally
(a[0]['f1'] = ``value`` ).
diff --git a/doc/source/user/basics.rec.rst b/doc/source/user/basics.rec.rst
index ce6c3b851..1be5af081 100644
--- a/doc/source/user/basics.rec.rst
+++ b/doc/source/user/basics.rec.rst
@@ -1,7 +1,7 @@
.. _structured_arrays:
-***************************************
-Structured arrays (aka "Record arrays")
-***************************************
+*****************
+Structured arrays
+*****************
.. automodule:: numpy.doc.structured_arrays
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py
index 73efdb6a9..66b889cc9 100644
--- a/numpy/add_newdocs.py
+++ b/numpy/add_newdocs.py
@@ -4629,7 +4629,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('view',
>>> print x
[(1, 20) (3, 4)]
- Using a view to convert an array to a record array:
+ Using a view to convert an array to a recarray:
>>> z = x.view(np.recarray)
>>> z.a
@@ -5875,17 +5875,18 @@ add_newdoc('numpy.core.multiarray', 'dtype',
>>> np.dtype(np.int16)
dtype('int16')
- Record, one field name 'f1', containing int16:
+ Structured type, one field name 'f1', containing int16:
>>> np.dtype([('f1', np.int16)])
dtype([('f1', '<i2')])
- Record, one field named 'f1', in itself containing a record with one field:
+ Structured type, one field named 'f1', in itself containing a structured
+ type with one field:
>>> np.dtype([('f1', [('f1', np.int16)])])
dtype([('f1', [('f1', '<i2')])])
- Record, two fields: the first field contains an unsigned int, the
+ Structured type, two fields: the first field contains an unsigned int, the
second an int32:
>>> np.dtype([('f1', np.uint), ('f2', np.int32)])
diff --git a/numpy/core/records.py b/numpy/core/records.py
index bf4d835ea..23680711f 100644
--- a/numpy/core/records.py
+++ b/numpy/core/records.py
@@ -3,9 +3,9 @@ Record Arrays
=============
Record arrays expose the fields of structured arrays as properties.
-Most commonly, ndarrays contain elements of a single type, e.g. floats, integers,
-bools etc. However, it is possible for elements to be combinations of these,
-such as::
+Most commonly, ndarrays contain elements of a single type, e.g. floats,
+integers, bools etc. However, it is possible for elements to be combinations
+of these using structured types, such as::
>>> a = np.array([(1, 2.0), (1, 2.0)], dtype=[('x', int), ('y', float)])
>>> a
@@ -25,7 +25,7 @@ one would a dictionary::
Record arrays allow us to access fields as properties::
- >>> ar = a.view(np.recarray)
+ >>> ar = np.rec.array(a)
>>> ar.x
array([1, 1])
diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c
index 3f91b748c..6e48ef381 100644
--- a/numpy/core/src/multiarray/arrayobject.c
+++ b/numpy/core/src/multiarray/arrayobject.c
@@ -732,7 +732,7 @@ array_might_be_written(PyArrayObject *obj)
{
const char *msg =
"Numpy has detected that you (may be) writing to an array returned\n"
- "by numpy.diagonal or by selecting multiple fields in a record\n"
+ "by numpy.diagonal or by selecting multiple fields in a structured\n"
"array. This code will likely break in a future numpy release --\n"
"see numpy.diagonal or arrays.indexing reference docs for details.\n"
"The quick fix is to make an explicit copy (e.g., do\n"
diff --git a/numpy/doc/creation.py b/numpy/doc/creation.py
index 7979b51aa..b10d45d48 100644
--- a/numpy/doc/creation.py
+++ b/numpy/doc/creation.py
@@ -17,7 +17,7 @@ There are 5 general mechanisms for creating arrays:
This section will not cover means of replicating, joining, or otherwise
expanding or mutating existing arrays. Nor will it cover creating object
-arrays or record arrays. Both of those are covered in their own sections.
+arrays or structured arrays. Both of those are covered in their own sections.
Converting Python array_like Objects to Numpy Arrays
====================================================
diff --git a/numpy/doc/glossary.py b/numpy/doc/glossary.py
index 3770f5761..f856a742b 100644
--- a/numpy/doc/glossary.py
+++ b/numpy/doc/glossary.py
@@ -284,7 +284,12 @@ Glossary
ndarray
See *array*.
-
+
+ record array
+ An `ndarray`_ with `structured data type`_ which has been subclassed as
+ np.recarray and whose dtype is of type np.record, making the
+ fields of its data type to be accessible by attribute.
+
reference
If ``a`` is a reference to ``b``, then ``(a is b) == True``. Therefore,
``a`` and ``b`` are different names for the same Python object.
@@ -345,7 +350,10 @@ Glossary
>>> x[:, 1]
array([2, 4])
-
+
+ structured data type
+ A data type composed of other datatypes
+
tuple
A sequence that may contain a variable number of types of any
kind. A tuple is immutable, i.e., once constructed it cannot be
diff --git a/numpy/doc/structured_arrays.py b/numpy/doc/structured_arrays.py
index 0444bdf90..f2329827e 100644
--- a/numpy/doc/structured_arrays.py
+++ b/numpy/doc/structured_arrays.py
@@ -1,34 +1,33 @@
"""
-=====================================
-Structured Arrays (and Record Arrays)
-=====================================
+=================
+Structured Arrays
+=================
Introduction
============
-Numpy provides powerful capabilities to create arrays of structs or records.
-These arrays permit one to manipulate the data by the structs or by fields of
-the struct. A simple example will show what is meant.: ::
+Numpy provides powerful capabilities to create arrays of structured datatype.
+These arrays permit one to manipulate the data by named fields. A simple
+example will show what is meant.: ::
- >>> x = np.zeros((2,),dtype=('i4,f4,a10'))
- >>> x[:] = [(1,2.,'Hello'),(2,3.,"World")]
+ >>> x = np.array([(1,2.,'Hello'), (2,3.,"World")],
+ ... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
>>> x
array([(1, 2.0, 'Hello'), (2, 3.0, 'World')],
- dtype=[('f0', '>i4'), ('f1', '>f4'), ('f2', '|S10')])
+ dtype=[('foo', '>i4'), ('bar', '>f4'), ('baz', '|S10')])
Here we have created a one-dimensional array of length 2. Each element of
-this array is a record that contains three items, a 32-bit integer, a 32-bit
+this array is a structure that contains three items, a 32-bit integer, a 32-bit
float, and a string of length 10 or less. If we index this array at the second
-position we get the second record: ::
+position we get the second structure: ::
>>> x[1]
(2,3.,"World")
Conveniently, one can access any field of the array by indexing using the
-string that names that field. In this case the fields have received the
-default names 'f0', 'f1' and 'f2'. ::
+string that names that field. ::
- >>> y = x['f1']
+ >>> y = x['foo']
>>> y
array([ 2., 3.], dtype=float32)
>>> y[:] = 2*y
@@ -36,19 +35,19 @@ default names 'f0', 'f1' and 'f2'. ::
array([ 4., 6.], dtype=float32)
>>> x
array([(1, 4.0, 'Hello'), (2, 6.0, 'World')],
- dtype=[('f0', '>i4'), ('f1', '>f4'), ('f2', '|S10')])
+ dtype=[('foo', '>i4'), ('bar', '>f4'), ('baz', '|S10')])
In these examples, y is a simple float array consisting of the 2nd field
-in the record. But, rather than being a copy of the data in the structured
+in the structured type. But, rather than being a copy of the data in the structured
array, it is a view, i.e., it shares exactly the same memory locations.
Thus, when we updated this array by doubling its values, the structured
array shows the corresponding values as doubled as well. Likewise, if one
-changes the record, the field view also changes: ::
+changes the structured array, the field view also changes: ::
>>> x[1] = (-1,-1.,"Master")
>>> x
array([(1, 4.0, 'Hello'), (-1, -1.0, 'Master')],
- dtype=[('f0', '>i4'), ('f1', '>f4'), ('f2', '|S10')])
+ dtype=[('foo', '>i4'), ('bar', '>f4'), ('baz', '|S10')])
>>> y
array([ 4., -1.], dtype=float32)
@@ -65,9 +64,10 @@ function keyword or a dtype object constructor itself). This
argument must be one of the following: 1) string, 2) tuple, 3) list, or
4) dictionary. Each of these is briefly described below.
-1) String argument (as used in the above examples).
+1) String argument.
In this case, the constructor expects a comma-separated list of type
-specifiers, optionally with extra shape information.
+specifiers, optionally with extra shape information. The fields are
+given the default names 'f0', 'f1', 'f2' and so on.
The type specifiers can take 4 different forms: ::
a) b1, i1, i2, i4, i8, u1, u2, u4, u8, f2, f4, f8, c8, c16, a<n>
@@ -152,7 +152,7 @@ values specifying type, offset, and an optional title. ::
Accessing and modifying field names
===================================
-The field names are an attribute of the dtype object defining the record structure.
+The field names are an attribute of the dtype object defining the structure.
For the last example: ::
>>> x.dtype.names
@@ -213,11 +213,88 @@ If you fill it in row by row, it takes a take a tuple
array([(10.0, 20.0), (1.0, 0.0), (2.0, 0.0), (3.0, 0.0), (4.0, 0.0)],
dtype=[('var1', '<f8'), ('var2', '<f8')])
-More information
-====================================
-You can find some more information on recarrays and structured arrays
-(including the difference between the two) `here
-<http://www.scipy.org/Cookbook/Recarray>`_.
+Record Arrays
+=============
+
+For convenience, numpy provides "record arrays" which allow one to access
+fields of structured arrays by attribute rather than by index. Record arrays
+are structured arrays wrapped using a subclass of ndarray,
+:class:`numpy.recarray`, which allows field access by attribute on the array
+object, and record arrays also use a special datatype, :class:`numpy.record`,
+which allows field access by attribute on the individual elements of 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")],
+ ... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'S10')])
+ >>> recordarr.bar
+ array([ 2., 3.], dtype=float32)
+ >>> recordarr[1:2]
+ rec.array([(2, 3.0, 'World')],
+ dtype=[('foo', '<i4'), ('bar', '<f4'), ('baz', 'S10')])
+ >>> recordarr[1:2].foo
+ array([2], dtype=int32)
+ >>> recordarr.foo[1:2]
+ array([2], dtype=int32)
+ >>> recordarr[1].baz
+ 'World'
+
+numpy.rec.array can convert a wide variety of arguments into record arrays,
+including normal structured arrays: ::
+
+ >>> arr = array([(1,2.,'Hello'),(2,3.,"World")],
+ ... dtype=[('foo', 'i4'), ('bar', 'f4'), ('baz', 'S10')])
+ >>> recordarr = np.rec.array(arr)
+
+The numpy.rec module provides a number of other convenience functions for
+creating record arrays, see :ref:`record array creation routines
+<routines.array-creation.rec>`.
+
+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")],
+ ... dtype=[('foo', 'i4'),('bar', 'f4'), ('baz', 'a10')])
+ >>> recordarr = arr.view(dtype=dtype((np.record, arr.dtype)),
+ ... type=np.recarray)
+
+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))],
+ ... dtype=[('foo', 'S6'),('bar', [('A', int), ('B', int)])])
+ >>> type(recordarr.foo)
+ <type 'numpy.ndarray'>
+ >>> type(recordarr.bar)
+ <class 'numpy.core.records.recarray'>
+
+Partial Attribute Access
+------------------------
+
+The differences between record arrays and plain structured arrays induce a
+small performance penalty. It is possible to apply one or the other view
+independently if desired. To allow field access by attribute only on the array
+object it is sufficient to view an array as a recarray: ::
+
+ >>> recarr = arr.view(np.recarray)
+
+This type of view is commonly used, for example in np.npyio and
+np.recfunctions. Note that unlike full record arrays the individual elements of
+such a view do not have field attributes::
+
+ >>> recarr[0].foo
+ AttributeError: 'numpy.void' object has no attribute 'foo'
+
+To use the np.record dtype only, convert the dtype using the (base_class,
+dtype) form described in numpy.dtype. This type of view is rarely used. ::
+
+ >>> arr_records = arr.view(dtype(np.record, arr.dtype))
+
+In documentation, the term 'structured array' will refer to objects of type
+np.ndarray with structured dtype, 'record array' will refer to structured
+arrays subclassed as np.recarray and whose dtype is of type np.record, and
+'recarray' will refer to arrays subclassed as np.recarray but whose dtype is
+not of type np.record.
"""
from __future__ import division, absolute_import, print_function
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py
index 5f274f27c..bedd0e941 100644
--- a/numpy/lib/npyio.py
+++ b/numpy/lib/npyio.py
@@ -656,7 +656,7 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
generators should return byte strings for Python 3k.
dtype : data-type, optional
Data-type of the resulting array; default: float. If this is a
- record data-type, the resulting array will be 1-dimensional, and
+ structured data-type, the resulting array will be 1-dimensional, and
each row will be interpreted as an element of the array. In this
case, the number of columns used must match the number of fields in
the data-type.
@@ -680,7 +680,7 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
The default, None, results in all columns being read.
unpack : bool, optional
If True, the returned array is transposed, so that arguments may be
- unpacked using ``x, y, z = loadtxt(...)``. When used with a record
+ unpacked using ``x, y, z = loadtxt(...)``. When used with a structured
data-type, arrays are returned for each field. Default is False.
ndmin : int, optional
The returned array will have at least `ndmin` dimensions.