diff options
Diffstat (limited to 'doc/source/reference')
-rw-r--r-- | doc/source/reference/arrays.dtypes.rst | 12 | ||||
-rw-r--r-- | doc/source/reference/arrays.indexing.rst | 402 | ||||
-rw-r--r-- | doc/source/reference/arrays.ndarray.rst | 1 | ||||
-rw-r--r-- | doc/source/reference/c-api.array.rst | 39 | ||||
-rw-r--r-- | doc/source/reference/c-api.generalized-ufuncs.rst | 26 | ||||
-rw-r--r-- | doc/source/reference/c-api.iterator.rst | 24 | ||||
-rw-r--r-- | doc/source/reference/c-api.types-and-structures.rst | 16 | ||||
-rw-r--r-- | doc/source/reference/maskedarray.baseclass.rst | 1 | ||||
-rw-r--r-- | doc/source/reference/routines.array-creation.rst | 2 | ||||
-rw-r--r-- | doc/source/reference/routines.ma.rst | 2 | ||||
-rw-r--r-- | doc/source/reference/routines.rst | 2 | ||||
-rw-r--r-- | doc/source/reference/routines.testing.rst | 3 | ||||
-rw-r--r-- | doc/source/reference/swig.interface-file.rst | 2 |
13 files changed, 370 insertions, 162 deletions
diff --git a/doc/source/reference/arrays.dtypes.rst b/doc/source/reference/arrays.dtypes.rst index 2fc1add99..797f1f6f8 100644 --- a/doc/source/reference/arrays.dtypes.rst +++ b/doc/source/reference/arrays.dtypes.rst @@ -220,16 +220,20 @@ One-character strings Array-protocol type strings (see :ref:`arrays.interface`) The first character specifies the kind of data and the remaining - characters specify how many bytes of data. The supported kinds are + characters specify the number of bytes per item. The item size may + be ignored for some kinds (i.e., boolean, object), rounded to the + next supported size (float, complex), or interpreted as the number + of characters (Unicode). The supported kinds are ================ ======================== - ``'b'`` Boolean + ``'b'`` boolean ``'i'`` (signed) integer ``'u'`` unsigned integer ``'f'`` floating-point ``'c'`` complex-floating point - ``'S'``, ``'a'`` string - ``'U'`` unicode + ``'O'`` (Python) objects + ``'S'``, ``'a'`` (byte-)string + ``'U'`` Unicode ``'V'`` raw data (:class:`void`) ================ ======================== diff --git a/doc/source/reference/arrays.indexing.rst b/doc/source/reference/arrays.indexing.rst index e759b6ff8..ef0180e0f 100644 --- a/doc/source/reference/arrays.indexing.rst +++ b/doc/source/reference/arrays.indexing.rst @@ -21,8 +21,8 @@ slicing, advanced indexing. Which one occurs depends on *obj*. for the former. -Basic Slicing -------------- +Basic Slicing and Indexing +-------------------------- Basic slicing extends Python's basic concept of slicing to N dimensions. Basic slicing occurs when *obj* is a :class:`slice` object @@ -31,9 +31,9 @@ integer, or a tuple of slice objects and integers. :const:`Ellipsis` and :const:`newaxis` objects can be interspersed with these as well. In order to remain backward compatible with a common usage in Numeric, basic slicing is also initiated if the selection object is -any sequence (such as a :class:`list`) containing :class:`slice` +any non-ndarray sequence (such as a :class:`list`) containing :class:`slice` objects, the :const:`Ellipsis` object, or the :const:`newaxis` object, -but no integer arrays or other embedded sequences. +but not for integer arrays or other embedded sequences. .. index:: triple: ndarray; special methods; getslice @@ -46,8 +46,8 @@ scalar <arrays.scalars>` representing the corresponding item. As in Python, all indices are zero-based: for the *i*-th index :math:`n_i`, the valid range is :math:`0 \le n_i < d_i` where :math:`d_i` is the *i*-th element of the shape of the array. Negative indices are -interpreted as counting from the end of the array (*i.e.*, if *i < 0*, -it means :math:`n_i + i`). +interpreted as counting from the end of the array (*i.e.*, if +:math:`n_i < 0`, it means :math:`n_i + d_i`). All arrays generated by basic slicing are always :term:`views <view>` @@ -84,7 +84,7 @@ concepts to remember include: - Assume *n* is the number of elements in the dimension being sliced. Then, if *i* is not given it defaults to 0 for *k > 0* and - *n* for *k < 0* . If *j* is not given it defaults to *n* for *k > 0* + *n - 1* for *k < 0* . If *j* is not given it defaults to *n* for *k > 0* and -1 for *k < 0* . If *k* is not given it defaults to 1. Note that ``::`` is the same as ``:`` and means select all indices along this axis. @@ -108,8 +108,8 @@ concepts to remember include: [6]]]) - :const:`Ellipsis` expand to the number of ``:`` objects needed to - make a selection tuple of the same length as ``x.ndim``. Only the - first ellipsis is expanded, any others are interpreted as ``:``. + make a selection tuple of the same length as ``x.ndim``. There may + only be a single ellipsis present. .. admonition:: Example @@ -148,7 +148,7 @@ concepts to remember include: ``x[ind1,...,ind2,:]`` acts like ``x[ind1][...,ind2,:]`` under basic slicing. - .. warning:: The above is **not** true for advanced slicing. + .. warning:: The above is **not** true for advanced indexing. - You may use slicing to set values in the array, but (unlike lists) you can never grow the array. The size of the value to be set in @@ -170,12 +170,12 @@ concepts to remember include: .. data:: newaxis - The :const:`newaxis` object can be used in all slicing operations - as discussed above. :const:`None` can also be used instead of - :const:`newaxis`. + The :const:`newaxis` object can be used in all slicing operations to + create an axis of length one. :const: :const:`newaxis` is an alias for + 'None', and 'None' can be used in place of this with the same result. -Advanced indexing +Advanced Indexing ----------------- Advanced indexing is triggered when the selection object, *obj*, is a @@ -187,139 +187,311 @@ and Boolean. Advanced indexing always returns a *copy* of the data (contrast with basic slicing that returns a :term:`view`). -Integer -^^^^^^^ +.. warning:: -Integer indexing allows selection of arbitrary items in the array -based on their *N*-dimensional index. This kind of selection occurs -when advanced indexing is triggered and the selection object is not -an array of data type bool. For the discussion below, when the -selection object is not a tuple, it will be referred to as if it had -been promoted to a 1-tuple, which will be called the selection -tuple. The rules of advanced integer-style indexing are: + The definition of advanced indexing means that ``x[(1,2,3),]`` is + fundamentally different than ``x[(1,2,3)]``. The latter is + equivalent to ``x[1,2,3]`` which will trigger basic selection while + the former will trigger advanced indexing. Be sure to understand + why this is occurs. -- If the length of the selection tuple is larger than *N* an error is raised. + Also recognize that ``x[[1,2,3]]`` will trigger advanced indexing, + whereas ``x[[1,2,slice(None)]]`` will trigger basic slicing. -- All sequences and scalars in the selection tuple are converted to - :class:`intp` indexing arrays. +Integer array indexing +^^^^^^^^^^^^^^^^^^^^^^ -- All selection tuple objects must be convertible to :class:`intp` - arrays, :class:`slice` objects, or the :const:`Ellipsis` object. +Integer array indexing allows selection of arbitrary items in the array +based on their *N*-dimensional index. Each integer array represents a number +of indexes into that dimension. -- The first :const:`Ellipsis` object will be expanded, and any other - :const:`Ellipsis` objects will be treated as full slice (``:``) - objects. The expanded :const:`Ellipsis` object is replaced with as - many full slice (``:``) objects as needed to make the length of the - selection tuple :math:`N`. +Purely integer array indexing +""""""""""""""""""""""""""""" -- If the selection tuple is smaller than *N*, then as many ``:`` - objects as needed are added to the end of the selection tuple so - that the modified selection tuple has length *N*. +When the index consists of as many integer arrays as the array being indexed +has dimensions, the indexing is straight forward, but different from slicing. -- All the integer indexing arrays must be :ref:`broadcastable - <arrays.broadcasting.broadcastable>` to the same shape. +Advanced indexes always are :ref:`broadcast<ufuncs.broadcasting>` and +iterated as *one*:: -- The shape of the output (or the needed shape of the object to be used - for setting) is the broadcasted shape. + result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M], + ..., ind_N[i_1, ..., i_M]] -- After expanding any ellipses and filling out any missing ``:`` - objects in the selection tuple, then let :math:`N_t` be the number - of indexing arrays, and let :math:`N_s = N - N_t` be the number of - slice objects. Note that :math:`N_t > 0` (or we wouldn't be doing - advanced integer indexing). +Note that the result shape is identical to the (broadcast) indexing array +shapes ``ind_1, ..., ind_N``. -- If :math:`N_s = 0` then the *M*-dimensional result is constructed by - varying the index tuple ``(i_1, ..., i_M)`` over the range - of the result shape and for each value of the index tuple - ``(ind_1, ..., ind_M)``:: +.. admonition:: Example - result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M], - ..., ind_N[i_1, ..., i_M]] + From each row, a specific element should be selected. The row index is just + ``[0, 1, 2]`` and the column index specifies the element to choose for the + corresponding row, here ``[0, 1, 0]``. Using both together the task + can be solved using advanced indexing: - .. admonition:: Example + >>> x = np.array([[1, 2], [3, 4], [5, 6]]) + >>> x[[0, 1, 2], [0, 1, 0]] + array([1, 4, 5]) - Suppose the shape of the broadcasted indexing arrays is 3-dimensional - and *N* is 2. Then the result is found by letting *i, j, k* run over - the shape found by broadcasting ``ind_1`` and ``ind_2``, and each - *i, j, k* yields:: - - result[i,j,k] = x[ind_1[i,j,k], ind_2[i,j,k]] - -- If :math:`N_s > 0`, then partial indexing is done. This can be - somewhat mind-boggling to understand, but if you think in terms of - the shapes of the arrays involved, it can be easier to grasp what - happens. In simple cases (*i.e.* one indexing array and *N - 1* slice - objects) it does exactly what you would expect (concatenation of - repeated application of basic slicing). The rule for partial - indexing is that the shape of the result (or the interpreted shape - of the object to be used in setting) is the shape of *x* with the - indexed subspace replaced with the broadcasted indexing subspace. If - the index subspaces are right next to each other, then the - broadcasted indexing space directly replaces all of the indexed - subspaces in *x*. If the indexing subspaces are separated (by slice - objects), then the broadcasted indexing space is first, followed by - the sliced subspace of *x*. +To achieve a behaviour similar to the basic slicing above, broadcasting can be +used. The function :func:`ix_` can help with this broadcasting. This is best +understood with an example. - .. admonition:: Example +.. admonition:: Example - Suppose ``x.shape`` is (10,20,30) and ``ind`` is a (2,3,4)-shaped - indexing :class:`intp` array, then ``result = x[...,ind,:]`` has - shape (10,2,3,4,30) because the (20,)-shaped subspace has been - replaced with a (2,3,4)-shaped broadcasted indexing subspace. If - we let *i, j, k* loop over the (2,3,4)-shaped subspace then - ``result[...,i,j,k,:] = x[...,ind[i,j,k],:]``. This example - produces the same result as :meth:`x.take(ind, axis=-2) <ndarray.take>`. + From a 4x3 array the corner elements should be selected using advanced + indexing. Thus all elements for which the column is one of ``[0, 2]`` and + the row is one of ``[0, 3]`` need to be selected. To use advanced indexing + one needs to select all elements *explicitly*. Using the method explained + previously one could write: + + >>> x = array([[ 0, 1, 2], + ... [ 3, 4, 5], + ... [ 6, 7, 8], + ... [ 9, 10, 11]]) + >>> rows = np.array([[0, 0], + ... [3, 3]], dtype=np.intp) + >>> columns = np.array([[0, 2], + ... [0, 2]], dtype=np.intp) + >>> x[rows, columns] + array([[ 0, 2], + [ 9, 11]]) + + However, since the indexing arrays above just repeat themselves, + broadcasting can be used (compare operations such as + ``rows[:, np.newaxis] + columns``) to simplify this: + + >>> rows = np.array([0, 3], dtype=np.intp) + >>> columns = np.array([0, 2], dtype=np.intp) + >>> rows[:, np.newaxis] + array([[0], + [3]]) + >>> x[rows[:, np.newaxis], columns] + array([[ 0, 2], + [ 9, 11]]) + + This broadcasting can also be achieved using the function :func:`ix_`: + + >>> x[np.ix_(rows, columns)] + array([[ 0, 2], + [ 9, 11]]) + + Note that without the ``np.ix_`` call, only the diagonal elements would + be selected, as was used in the previous example. This difference is the + most important thing to remember about indexing with multiple advanced + indexes. + +Combining advanced and basic indexing +""""""""""""""""""""""""""""""""""""" + +When there is at least one slice (``:``), ellipsis (``...``) or ``np.newaxis`` +in the index (or the array has more dimensions than there are advanced indexes), +then the behaviour can be more complicated. It is like concatenating the +indexing result for each advanced index element + +In the simplest case, there is only a *single* advanced index. A single +advanced index can for example replace a slice and the result array will be +the same, however, it is a copy and may have a different memory layout. +A slice is preferable when it is possible. - .. admonition:: Example +.. admonition:: Example + + >>> x[1:2, 1:3] + array([[4, 5]]) + >>> x[1:2, [1, 2]] + array([[4, 5]]) + +The easiest way to understand the situation may be to think in +terms of the result shape. There are two parts to the indexing operation, +the subspace defined by the basic indexing (excluding integers) and the +subspace from the advanced indexing part. Two cases of index combination +need to be distinguished: + +* The advanced indexes are separated by a slice, ellipsis or newaxis. + For example ``x[arr1, :, arr2]``. +* The advanced indexes are all next to each other. + For example ``x[..., arr1, arr2, :]`` but *not* ``x[arr1, :, 1]`` + since ``1`` is an advanced index in this regard. + +In the first case, the dimensions resulting from the advanced indexing +operation come first in the result array, and the subspace dimensions after +that. +In the second case, the dimensions from the advanced indexing operations +are inserted into the result array at the same spot as they were in the +initial array (the latter logic is what makes simple advanced indexing +behave just like slicing). + +.. admonition:: Example + + Suppose ``x.shape`` is (10,20,30) and ``ind`` is a (2,3,4)-shaped + indexing :class:`intp` array, then ``result = x[...,ind,:]`` has + shape (10,2,3,4,30) because the (20,)-shaped subspace has been + replaced with a (2,3,4)-shaped broadcasted indexing subspace. If + we let *i, j, k* loop over the (2,3,4)-shaped subspace then + ``result[...,i,j,k,:] = x[...,ind[i,j,k],:]``. This example + produces the same result as :meth:`x.take(ind, axis=-2) <ndarray.take>`. + +.. admonition:: Example - Now let ``x.shape`` be (10,20,30,40,50) and suppose ``ind_1`` - and ``ind_2`` are broadcastable to the shape (2,3,4). Then - ``x[:,ind_1,ind_2]`` has shape (10,2,3,4,40,50) because the - (20,30)-shaped subspace from X has been replaced with the - (2,3,4) subspace from the indices. However, - ``x[:,ind_1,:,ind_2]`` has shape (2,3,4,10,30,50) because there - is no unambiguous place to drop in the indexing subspace, thus - it is tacked-on to the beginning. It is always possible to use - :meth:`.transpose() <ndarray.transpose>` to move the subspace - anywhere desired. (Note that this example cannot be replicated - using :func:`take`.) + Let ``x.shape`` be (10,20,30,40,50) and suppose ``ind_1`` + and ``ind_2`` can be broadcast to the shape (2,3,4). Then + ``x[:,ind_1,ind_2]`` has shape (10,2,3,4,40,50) because the + (20,30)-shaped subspace from X has been replaced with the + (2,3,4) subspace from the indices. However, + ``x[:,ind_1,:,ind_2]`` has shape (2,3,4,10,30,50) because there + is no unambiguous place to drop in the indexing subspace, thus + it is tacked-on to the beginning. It is always possible to use + :meth:`.transpose() <ndarray.transpose>` to move the subspace + anywhere desired. Note that this example cannot be replicated + using :func:`take`. -Boolean -^^^^^^^ +Boolean array indexing +^^^^^^^^^^^^^^^^^^^^^^ This advanced indexing occurs when obj is an array object of Boolean -type (such as may be returned from comparison operators). It is always -equivalent to (but faster than) ``x[obj.nonzero()]`` where, as -described above, :meth:`obj.nonzero() <ndarray.nonzero>` returns a +type, such as may be returned from comparison operators. A single +boolean index array is practically identical to ``x[obj.nonzero()]`` where, +as described above, :meth:`obj.nonzero() <ndarray.nonzero>` returns a tuple (of length :attr:`obj.ndim <ndarray.ndim>`) of integer index -arrays showing the :const:`True` elements of *obj*. +arrays showing the :const:`True` elements of *obj*. However, it is +faster when ``obj.shape == x.shape``. -The special case when ``obj.ndim == x.ndim`` is worth mentioning. In -this case ``x[obj]`` returns a 1-dimensional array filled with the -elements of *x* corresponding to the :const:`True` values of *obj*. +If ``obj.ndim == x.ndim``, ``x[obj]`` returns a 1-dimensional array +filled with the elements of *x* corresponding to the :const:`True` +values of *obj*. The search order will be C-style (last index varies the fastest). If *obj* has :const:`True` values at entries that are outside of the -bounds of *x*, then an index error will be raised. +bounds of *x*, then an index error will be raised. If *obj* is smaller +than *x* it is identical to filling it with :const:`False`. -You can also use Boolean arrays as element of the selection tuple. In -such instances, they will always be interpreted as :meth:`nonzero(obj) -<ndarray.nonzero>` and the equivalent integer indexing will be -done. +.. admonition:: Example -.. warning:: + A common use case for this is filtering for desired element values. + For example one may wish to select all entries from an array which + are not NaN: - The definition of advanced indexing means that ``x[(1,2,3),]`` is - fundamentally different than ``x[(1,2,3)]``. The latter is - equivalent to ``x[1,2,3]`` which will trigger basic selection while - the former will trigger advanced indexing. Be sure to understand - why this is occurs. + >>> x = np.array([[1., 2.], [np.nan, 3.], [np.nan, np.nan]]) + >>> x[~np.isnan(x)] + array([ 1., 2., 3.]) - Also recognize that ``x[[1,2,3]]`` will trigger advanced indexing, - whereas ``x[[1,2,slice(None)]]`` will trigger basic slicing. + Or wish to add a constant to all negative elements: + + >>> x = np.array([1., -1., -2., 3]) + >>> x[x < 0] += 20 + >>> x + array([ 1., 19., 18., 3.]) + +In general if an index includes a Boolean array, the result will be +identical to inserting ``obj.nonzero()`` into the same position +and using the integer array indexing mechanism described above. +``x[ind_1, boolean_array, ind_2]`` is equivalent to +``x[(ind_1,) + boolean_array.nonzero() + (ind_2,)]``. + +If there is only one Boolean array and no integer indexing array present, +this is straight forward. Care must only be taken to make sure that the +boolean index has *exactly* as many dimensions as it is supposed to work +with. + +.. admonition:: Example + + From an array, select all rows which sum up to less or equal two: + + >>> x = np.array([[0, 1], [1, 1], [2, 2]]) + >>> rowsum = x.sum(-1) + >>> x[rowsum <= 2, :] + array([[0, 1], + [1, 1]]) + + But if ``rowsum`` would have two dimensions as well: + + >>> rowsum = x.sum(-1, keepdims=True) + >>> rowsum.shape + (3, 1) + >>> x[rowsum <= 2, :] # fails + IndexError: too many indices + >>> x[rowsum <= 2] + array([0, 1]) + + The last one giving only the first elements because of the extra dimension. + Compare ``rowsum.nonzero()`` to understand this example. + +Combining multiple Boolean indexing arrays or a Boolean with an integer +indexing array can best be understood with the +:meth:`obj.nonzero() <ndarray.nonzero>` analogy. The function :func:`ix_` +also supports boolean arrays and will work without any surprises. + +.. admonition:: Example + + Use boolean indexing to select all rows adding up to an even + number. At the same time columns 0 and 2 should be selected with an + advanced integer index. Using the :func:`ix_` function this can be done + with: + + >>> x = array([[ 0, 1, 2], + ... [ 3, 4, 5], + ... [ 6, 7, 8], + ... [ 9, 10, 11]]) + >>> rows = (x.sum(-1) % 2) == 0 + >>> rows + array([False, True, False, True], dtype=bool) + >>> columns = [0, 2] + >>> x[np.ix_(rows, columns)] + array([[ 3, 5], + [ 9, 11]]) + + Without the ``np.ix_`` call or only the diagonal elements would be + selected. + + Or without ``np.ix_`` (compare the integer array examples): + + >>> rows = rows.nonzero()[0] + >>> x[rows[:, np.newaxis], columns] + array([[ 3, 5], + [ 9, 11]]) + +Detailed notes +-------------- + +These are some detailed notes, which are not of importance for day to day +indexing (in no particular order): + +* The native NumPy indexing type is ``intp`` and may differ from the + default integer array type. ``intp`` is the smallest data type + sufficient to safely index any array; for advanced indexing it may be + faster than other types. +* For advanced assignments, there is in general no guarantee for the + iteration order. This means that if an element is set more than once, + it is not possible to predict the final result. +* An empty (tuple) index is a full scalar index into a zero dimensional array. + ``x[()]`` returns a *scalar* if ``x`` is zero dimensional and a view + otherwise. On the other hand ``x[...]`` always returns a view. +* If a zero dimensional array is present in the index *and* it is a full + integer index the result will be a *scalar* and not a zero dimensional array. + (Advanced indexing is not triggered.) +* When an ellipsis (``...``) is present but has no size (i.e. replaces zero + ``:``) the result will still always be an array. A view if no advanced index + is present, otherwise a copy. +* the ``nonzero`` equivalence for Boolean arrays does not hold for zero + dimensional boolean arrays. +* When the result of an advanced indexing operation has no elements but an + individual index is out of bounds, whether or not an ``IndexError`` is + raised is undefined (e.g. ``x[[], [123]]`` with ``123`` being out of bounds). +* When a *casting* error occurs during assignment (for example updating a + numerical array using a sequence of strings), the array being assigned + to may end up in an unpredictable partially updated state. + However, if any other error (such as an out of bounds index) occurs, the + array will remain unchanged. +* The memory layout of an advanced indexing result is optimized for each + indexing operation and no particular memory order can be assumed. +* When using a subclass (especially one which manipulates its shape), the + default ``ndarray.__setitem__`` behaviour will call ``__getitem__`` for + *basic* indexing but not for *advanced* indexing. For such a subclass it may + be preferable to call ``ndarray.__setitem__`` with a *base class* ndarray + view on the data. This *must* be done if the subclasses ``__getitem__`` does + not return views. .. _arrays.indexing.rec: + Record Access ------------- diff --git a/doc/source/reference/arrays.ndarray.rst b/doc/source/reference/arrays.ndarray.rst index 85e41c215..e9c0a6d87 100644 --- a/doc/source/reference/arrays.ndarray.rst +++ b/doc/source/reference/arrays.ndarray.rst @@ -294,6 +294,7 @@ Array conversion ndarray.itemset ndarray.setasflat ndarray.tostring + ndarray.tobytes ndarray.tofile ndarray.dump ndarray.dumps diff --git a/doc/source/reference/c-api.array.rst b/doc/source/reference/c-api.array.rst index 6e68a9a0e..baf804378 100644 --- a/doc/source/reference/c-api.array.rst +++ b/doc/source/reference/c-api.array.rst @@ -190,7 +190,7 @@ From scratch .. cfunction:: PyObject* PyArray_NewFromDescr(PyTypeObject* subtype, PyArray_Descr* descr, int nd, npy_intp* dims, npy_intp* strides, void* data, int flags, PyObject* obj) - This function steals a reference to *descr* if it is not NULL. + This function steals a reference to *descr*. This is the main array creation function. Most new arrays are created with this flexible function. @@ -1036,7 +1036,10 @@ Converting data types the casting rule *casting*. For simple types with :cdata:`NPY_SAFE_CASTING`, this is basically a wrapper around :cfunc:`PyArray_CanCastSafely`, but for flexible types such as strings or unicode, it produces results - taking into account their sizes. + taking into account their sizes. Integer and float types can only be cast + to a string or unicode type using :cdata:`NPY_SAFE_CASTING` if the string + or unicode type is big enough to hold the max value of the integer/float + type being cast from. .. cfunction:: int PyArray_CanCastArrayTo(PyArrayObject* arr, PyArray_Descr* totype, NPY_CASTING casting) @@ -1073,7 +1076,8 @@ Converting data types Finds the data type of smallest size and kind to which *type1* and *type2* may be safely converted. This function is symmetric and - associative. + associative. A string or unicode result will be the proper size for + storing the max value of the input types converted to a string or unicode. .. cfunction:: PyArray_Descr* PyArray_ResultType(npy_intp narrs, PyArrayObject**arrs, npy_intp ndtypes, PyArray_Descr**dtypes) @@ -1574,7 +1578,7 @@ Conversion .. cfunction:: PyObject* PyArray_ToString(PyArrayObject* self, NPY_ORDER order) - Equivalent to :meth:`ndarray.tostring` (*self*, *order*). Return the bytes + Equivalent to :meth:`ndarray.tobytes` (*self*, *order*). Return the bytes of this array in a Python string. .. cfunction:: PyObject* PyArray_ToFile(PyArrayObject* self, FILE* fp, char* sep, char* format) @@ -1628,11 +1632,11 @@ Conversion Shape Manipulation ^^^^^^^^^^^^^^^^^^ -.. cfunction:: PyObject* PyArray_Newshape(PyArrayObject* self, PyArray_Dims* newshape) +.. cfunction:: PyObject* PyArray_Newshape(PyArrayObject* self, PyArray_Dims* newshape, NPY_ORDER order) Result will be a new array (pointing to the same memory location - as *self* if possible), but having a shape given by *newshape* - . If the new shape is not compatible with the strides of *self*, + as *self* if possible), but having a shape given by *newshape*. + If the new shape is not compatible with the strides of *self*, then a copy of the array with the new specified shape will be returned. @@ -1641,6 +1645,7 @@ Shape Manipulation Equivalent to :meth:`ndarray.reshape` (*self*, *shape*) where *shape* is a sequence. Converts *shape* to a :ctype:`PyArray_Dims` structure and calls :cfunc:`PyArray_Newshape` internally. + For back-ward compatability -- Not recommended .. cfunction:: PyObject* PyArray_Squeeze(PyArrayObject* self) @@ -1877,6 +1882,18 @@ Calculation Equivalent to :meth:`ndarray.argmin` (*self*, *axis*). Return the index of the smallest element of *self* along *axis*. + + + +.. note:: + + The out argument specifies where to place the result. If out is + NULL, then the output array is created, otherwise the output is + placed in out which must be the correct size and type. A new + reference to the ouput array is always returned even when out + is not NULL. The caller of the routine has the responsability + to ``DECREF`` out if not NULL or a memory-leak will occur. + .. cfunction:: PyObject* PyArray_Max(PyArrayObject* self, int axis, PyArrayObject* out) Equivalent to :meth:`ndarray.max` (*self*, *axis*). Return the largest @@ -2583,7 +2600,7 @@ Data-type descriptors unless otherwise noted. Therefore, you must own a reference to any data-type object used as input to such a function. -.. cfunction:: int PyArrayDescr_Check(PyObject* obj) +.. cfunction:: int PyArray_DescrCheck(PyObject* obj) Evaluates as true if *obj* is a data-type object ( :ctype:`PyArray_Descr *` ). @@ -2883,10 +2900,14 @@ the C-API is needed then some additional steps must be taken. .. code-block:: c - #define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API #define NO_IMPORT_ARRAY + #define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API #include numpy/arrayobject.h + You can also put the common two last lines into an extension-local + header file as long as you make sure that NO_IMPORT_ARRAY is + #defined before #including that file. + Checking the API Version ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/source/reference/c-api.generalized-ufuncs.rst b/doc/source/reference/c-api.generalized-ufuncs.rst index 870e5dbc4..14f33efcb 100644 --- a/doc/source/reference/c-api.generalized-ufuncs.rst +++ b/doc/source/reference/c-api.generalized-ufuncs.rst @@ -3,15 +3,12 @@ Generalized Universal Function API ================================== There is a general need for looping over not only functions on scalars -but also over functions on vectors (or arrays), as explained on -http://scipy.org/scipy/numpy/wiki/GeneralLoopingFunctions. We propose -to realize this concept by generalizing the universal functions -(ufuncs), and provide a C implementation that adds ~500 lines -to the numpy code base. In current (specialized) ufuncs, the elementary -function is limited to element-by-element operations, whereas the -generalized version supports "sub-array" by "sub-array" operations. -The Perl vector library PDL provides a similar functionality and its -terms are re-used in the following. +but also over functions on vectors (or arrays). +This concept is realized in Numpy by generalizing the universal functions +(ufuncs). In regular ufuncs, the elementary function is limited to +element-by-element operations, whereas the generalized version (gufuncs) +supports "sub-array" by "sub-array" operations. The Perl vector library PDL +provides a similar functionality and its terms are re-used in the following. Each generalized ufunc has information associated with it that states what the "core" dimensionality of the inputs is, as well as the @@ -21,12 +18,12 @@ arguments is called the "signature" of a ufunc. For example, the ufunc numpy.add has signature ``(),()->()`` defining two scalar inputs and one scalar output. -Another example is (see the GeneralLoopingFunctions page) the function -``inner1d(a,b)`` with a signature of ``(i),(i)->()``. This applies the -inner product along the last axis of each input, but keeps the -remaining indices intact. For example, where ``a`` is of shape ``(3,5,N)`` +Another example is the function ``inner1d(a,b)`` with a signature of +``(i),(i)->()``. This applies the inner product along the last axis of +each input, but keeps the remaining indices intact. +For example, where ``a`` is of shape ``(3,5,N)`` and ``b`` is of shape ``(5,N)``, this will return an output of shape ``(3,5)``. -The underlying elementary function is called 3*5 times. In the +The underlying elementary function is called ``3 * 5`` times. In the signature, we specify one core dimension ``(i)`` for each input and zero core dimensions ``()`` for the output, since it takes two 1-d arrays and returns a scalar. By using the same name ``i``, we specify that the two @@ -47,7 +44,6 @@ into core and loop dimensions: #. The output is given by the loop dimensions plus the output core dimensions. - Definitions ----------- diff --git a/doc/source/reference/c-api.iterator.rst b/doc/source/reference/c-api.iterator.rst index b26845434..084fdcbce 100644 --- a/doc/source/reference/c-api.iterator.rst +++ b/doc/source/reference/c-api.iterator.rst @@ -229,7 +229,7 @@ is used to control the memory layout of the allocated result, typically npy_intp i; do { npy_intp size = *innersizeptr; - char *src = dataaddr[0], *dst = dataaddr[1]; + char *src = dataptrarray[0], *dst = dataptrarray[1]; for(i = 0; i < size; i++, src += innerstride, dst += itemsize) { memcpy(dst, src, itemsize); } @@ -369,7 +369,14 @@ Construction and Destruction Causes the iterator to track a multi-index. This prevents the iterator from coalescing axes to - produce bigger inner loops. + produce bigger inner loops. If the loop is also not buffered + and no index is being tracked (`NpyIter_RemoveAxis` can be called), + then the iterator size can be ``-1`` to indicate that the iterator + is too large. This can happen due to complex broadcasting and + will result in errors being created when the setting the iterator + range, removing the multi index, or getting the next function. + However, it is possible to remove axes again and use the iterator + normally if the size is small enough after removal. .. cvar:: NPY_ITER_EXTERNAL_LOOP @@ -412,8 +419,9 @@ Construction and Destruction Indicates that arrays with a size of zero should be permitted. Since the typical iteration loop does not naturally work with - zero-sized arrays, you must check that the IterSize is non-zero - before entering the iteration loop. + zero-sized arrays, you must check that the IterSize is larger + than zero before entering the iteration loop. + Currently only the operands are checked, not a forced shape. .. cvar:: NPY_ITER_REDUCE_OK @@ -721,7 +729,7 @@ Construction and Destruction **WARNING**: This function may change the internal memory layout of the iterator. Any cached functions or pointers from the iterator - must be retrieved again! + must be retrieved again! The iterator range will be reset as well. Returns ``NPY_SUCCEED`` or ``NPY_FAIL``. @@ -887,7 +895,11 @@ Construction and Destruction .. cfunction:: npy_intp NpyIter_GetIterSize(NpyIter* iter) Returns the number of elements being iterated. This is the product - of all the dimensions in the shape. + of all the dimensions in the shape. When a multi index is being tracked + (and `NpyIter_RemoveAxis` may be called) the size may be ``-1`` to + indicate an iterator is too large. Such an iterator is invalid, but + may become valid after `NpyIter_RemoveAxis` is called. It is not + necessary to check for this case. .. cfunction:: npy_intp NpyIter_GetIterIndex(NpyIter* iter) diff --git a/doc/source/reference/c-api.types-and-structures.rst b/doc/source/reference/c-api.types-and-structures.rst index 79a888912..4e32ab7be 100644 --- a/doc/source/reference/c-api.types-and-structures.rst +++ b/doc/source/reference/c-api.types-and-structures.rst @@ -466,10 +466,10 @@ PyArrayDescr_Type A pointer to a function that compares two elements of the array, ``arr``, pointed to by ``d1`` and ``d2``. This - function requires behaved arrays. The return value is 1 if * - ``d1`` > * ``d2``, 0 if * ``d1`` == * ``d2``, and -1 if * - ``d1`` < * ``d2``. The array object arr is used to retrieve - itemsize and field information for flexible arrays. + function requires behaved (aligned and not swapped) arrays. + The return value is 1 if * ``d1`` > * ``d2``, 0 if * ``d1`` == * + ``d2``, and -1 if * ``d1`` < * ``d2``. The array object ``arr`` is + used to retrieve itemsize and field information for flexible arrays. .. cmember:: int argmax(void* data, npy_intp n, npy_intp* max_ind, void* arr) @@ -646,9 +646,9 @@ PyUFunc_Type void **data; int ntypes; int check_return; - char *name; + const char *name; char *types; - char *doc; + const char *doc; void *ptr; PyObject *obj; PyObject *userloops; @@ -1119,8 +1119,8 @@ PyArrayInterface A character indicating what kind of array is present according to the typestring convention with 't' -> bitfield, 'b' -> Boolean, 'i' -> signed integer, 'u' -> unsigned integer, 'f' -> floating point, 'c' -> - complex floating point, 'O' -> object, 'S' -> string, 'U' -> unicode, - 'V' -> void. + complex floating point, 'O' -> object, 'S' -> (byte-)string, 'U' -> + unicode, 'V' -> void. .. cmember:: int PyArrayInterface.itemsize diff --git a/doc/source/reference/maskedarray.baseclass.rst b/doc/source/reference/maskedarray.baseclass.rst index fd1fd7ae6..a1c90a45d 100644 --- a/doc/source/reference/maskedarray.baseclass.rst +++ b/doc/source/reference/maskedarray.baseclass.rst @@ -200,6 +200,7 @@ Conversion MaskedArray.tolist MaskedArray.torecords MaskedArray.tostring + MaskedArray.tobytes Shape manipulation diff --git a/doc/source/reference/routines.array-creation.rst b/doc/source/reference/routines.array-creation.rst index 23b35243b..c7c6ab815 100644 --- a/doc/source/reference/routines.array-creation.rst +++ b/doc/source/reference/routines.array-creation.rst @@ -20,6 +20,8 @@ Ones and zeros ones_like zeros zeros_like + full + full_like From existing data ------------------ diff --git a/doc/source/reference/routines.ma.rst b/doc/source/reference/routines.ma.rst index 6eda37578..5cb38e83f 100644 --- a/doc/source/reference/routines.ma.rst +++ b/doc/source/reference/routines.ma.rst @@ -251,7 +251,7 @@ Conversion operations ma.MaskedArray.tofile ma.MaskedArray.tolist ma.MaskedArray.torecords - ma.MaskedArray.tostring + ma.MaskedArray.tobytes Pickling and unpickling diff --git a/doc/source/reference/routines.rst b/doc/source/reference/routines.rst index 37b16de59..c2f091d83 100644 --- a/doc/source/reference/routines.rst +++ b/doc/source/reference/routines.rst @@ -36,8 +36,6 @@ indentation. routines.ma routines.math routines.matlib - routines.numarray - routines.oldnumeric routines.other routines.padding routines.polynomials diff --git a/doc/source/reference/routines.testing.rst b/doc/source/reference/routines.testing.rst index c0bcdaaeb..c43aeeed9 100644 --- a/doc/source/reference/routines.testing.rst +++ b/doc/source/reference/routines.testing.rst @@ -11,7 +11,7 @@ work right away. Asserts -======= +------- .. autosummary:: :toctree: generated/ @@ -25,6 +25,7 @@ Asserts assert_array_less assert_equal assert_raises + assert_raises_regex assert_warns assert_string_equal diff --git a/doc/source/reference/swig.interface-file.rst b/doc/source/reference/swig.interface-file.rst index d835a4c4f..c381feb85 100644 --- a/doc/source/reference/swig.interface-file.rst +++ b/doc/source/reference/swig.interface-file.rst @@ -166,7 +166,7 @@ assignments in lines 19 and 20. Using numpy.i ------------- -The ``numpy.i`` file is currently located in the ``numpy/docs/swig`` +The ``numpy.i`` file is currently located in the ``tools/swig`` sub-directory under the ``numpy`` installation directory. Typically, you will want to copy it to the directory where you are developing your wrappers. |