diff options
Diffstat (limited to 'doc/source')
35 files changed, 492 insertions, 280 deletions
diff --git a/doc/source/_templates/indexcontent.html b/doc/source/_templates/indexcontent.html index fb753e7b7..e3fe3ac9b 100644 --- a/doc/source/_templates/indexcontent.html +++ b/doc/source/_templates/indexcontent.html @@ -34,6 +34,7 @@ <td width="50%"> <p class="biglink"><a class="biglink" href="{{ pathto("bugs") }}">Reporting bugs</a></p> <p class="biglink"><a class="biglink" href="{{ pathto("about") }}">About NumPy</a></p> + <p class="biglink"><a class="biglink" href="{{ pathto("neps/index") }}">Numpy Enhancement Proposals</a><br/> </td><td width="50%"> <p class="biglink"><a class="biglink" href="{{ pathto("release") }}">Release Notes</a></p> <p class="biglink"><a class="biglink" href="{{ pathto("license") }}">License of Numpy</a></p> @@ -47,12 +48,14 @@ Public Domain in August 2008). The reference documentation for many of the functions are written by numerous contributors and developers of Numpy, both prior to and during the - <a href="http://scipy.org/Developer_Zone/DocMarathon2008">Numpy Documentation Marathon</a>. + <a href="http://docs.scipy.org/numpy/">Numpy Documentation Marathon</a>. </p> <p> - The Documentation Marathon is still ongoing. Please help us write - better documentation for Numpy by joining it! Instructions on how to - join and what to do can be found - <a href="http://scipy.org/Developer_Zone/DocMarathon2008">on the scipy.org website</a>. + The preferred way to update the documentation is by submitting a pull + request on Github (see the + <a href="http://docs.scipy.org/doc/numpy-dev/dev/">Developer Guide</a>. + The <a href="http://docs.scipy.org/numpy/">Numpy Documentation Wiki</a> + can also still be used to submit documentation fixes. + Please help us to further improve the Numpy documentation! </p> {% endblock %} diff --git a/doc/source/contents.rst b/doc/source/contents.rst index 023ebb8a0..1d46e8c7b 100644 --- a/doc/source/contents.rst +++ b/doc/source/contents.rst @@ -8,6 +8,7 @@ Numpy manual contents reference/index f2py/index dev/index + neps/index release about bugs diff --git a/doc/source/f2py/python-usage.rst b/doc/source/f2py/python-usage.rst index 83454c440..c7c7e3fd0 100644 --- a/doc/source/f2py/python-usage.rst +++ b/doc/source/f2py/python-usage.rst @@ -17,20 +17,14 @@ computational part of such functions is implemented in C or Fortran and wrapped with F2PY (or any other tool capable of providing CObject of a function). -.. example:: - - Consider a `Fortran 77 file`__ ``ftype.f``: +Consider a Fortran 77 file ``ftype.f``: .. include:: ftype.f :literal: - and build a wrapper using:: - - f2py -c ftype.f -m ftype +and build a wrapper using ``f2py -c ftype.f -m ftype``. - __ ftype.f - - In Python: +In Python: .. include:: ftype_session.dat :literal: @@ -54,18 +48,14 @@ type-casting only the real part of a complex number is used. order to *in situ* changes to be effective. It is recommended to use arrays with proper type but also other types work. -.. example:: - - Consider the following `Fortran 77 code`__: +Consider the following Fortran 77 code: .. include:: scalar.f :literal: - and wrap it using ``f2py -c -m scalar scalar.f``. +and wrap it using ``f2py -c -m scalar scalar.f``. - __ scalar.f - - In Python: +In Python: .. include:: scalar_session.dat :literal: @@ -88,18 +78,14 @@ Because Python strings are immutable, an ``intent(inout)`` argument expects an array version of a string in order to *in situ* changes to be effective. -.. example:: - - Consider the following `Fortran 77 code`__: +Consider the following Fortran 77 code: .. include:: string.f :literal: - and wrap it using ``f2py -c -m mystring string.f``. +and wrap it using ``f2py -c -m mystring string.f``. - __ string.f - - Python session: +Python session: .. include:: string_session.dat :literal: @@ -164,18 +150,14 @@ them to Fortran routines, use a function ``as_column_major_storage(<array>)`` that is provided by all F2PY generated extension modules. -.. example:: - - Consider `Fortran 77 code`__: +Consider Fortran 77 code: .. include:: array.f :literal: - and wrap it using ``f2py -c -m arr array.f -DF2PY_REPORT_ON_ARRAY_COPY=1``. +and wrap it using ``f2py -c -m arr array.f -DF2PY_REPORT_ON_ARRAY_COPY=1``. - __ array.f - - In Python: +In Python: .. include:: array_session.dat :literal: @@ -187,19 +169,14 @@ Call-back arguments F2PY supports calling Python functions from Fortran or C codes. - -.. example:: - - Consider the following `Fortran 77 code`__ +Consider the following Fortran 77 code: .. include:: callback.f :literal: - and wrap it using ``f2py -c -m callback callback.f``. - - __ callback.f +and wrap it using ``f2py -c -m callback callback.f``. - In Python: +In Python: .. include:: callback_session.dat :literal: @@ -217,53 +194,41 @@ block, use ``use`` statement as illustrated below. The same signature of a callback argument can be referred in different routine signatures. -.. example:: - - We use the same `Fortran 77 code`__ as in previous example but now - we'll pretend that F2PY was not able to guess the signatures of - call-back arguments correctly. First, we create an initial signature - file ``callback2.pyf`` using F2PY:: +We use the same Fortran 77 code as in previous example but now +we'll pretend that F2PY was not able to guess the signatures of +call-back arguments correctly. First, we create an initial signature +file ``callback2.pyf`` using F2PY:: f2py -m callback2 -h callback2.pyf callback.f - Then modify it as follows +Then modify it as follows .. include:: callback2.pyf :literal: - Finally, build the extension module using:: - - f2py -c callback2.pyf callback.f - - An example Python session would be identical to the previous example - except that argument names would differ. +Finally, build the extension module using ``f2py -c callback2.pyf callback.f``. - __ callback.f +An example Python session would be identical to the previous example +except that argument names would differ. Sometimes a Fortran package may require that users provide routines that the package will use. F2PY can construct an interface to such routines so that Python functions could be called from Fortran. -.. example:: - - Consider the following `Fortran 77 subroutine`__ that takes an array - and applies a function ``func`` to its elements. +Consider the following `Fortran 77 subroutine`__ that takes an array +and applies a function ``func`` to its elements. .. include:: calculate.f :literal: - __ calculate.f - - It is expected that function ``func`` has been defined - externally. In order to use a Python function as ``func``, it must - have an attribute ``intent(callback)`` (it must be specified before - the ``external`` statement). +It is expected that function ``func`` has been defined +externally. In order to use a Python function as ``func``, it must +have an attribute ``intent(callback)`` (it must be specified before +the ``external`` statement). - Finally, build an extension module using:: +Finally, build an extension module using ``f2py -c -m foo calculate.f`` - f2py -c -m foo calculate.f - - In Python: +In Python: .. include:: calculate_session.dat :literal: @@ -278,18 +243,14 @@ Then it is not necessary to pass the function in the argument list to the Fortran function. This may be desired if the Fortran function calling the python callback function is itself called by another Fortran function. -.. example:: - - Consider the following `Fortran 77 subroutine`__. +Consider the following Fortran 77 subroutine: .. include:: extcallback.f :literal: - __ extcallback.f +and wrap it using ``f2py -c -m pfromf extcallback.f``. - and wrap it using ``f2py -c -m pfromf extcallback.f``. - - In Python: +In Python: .. include:: extcallback_session.dat :literal: @@ -343,7 +304,6 @@ following rules are applied: * If ``k > l``, then only ``x_1, ..., x_l`` are set. - Common blocks ============== @@ -359,61 +319,51 @@ directly link to data members in common blocks. Data members can be changed by direct assignment or by in-place changes to the corresponding array objects. -.. example:: - - Consider the following `Fortran 77 code`__ +Consider the following Fortran 77 code: .. include:: common.f :literal: - and wrap it using ``f2py -c -m common common.f``. +and wrap it using ``f2py -c -m common common.f``. - __ common.f - - In Python: +In Python: .. include:: common_session.dat :literal: + Fortran 90 module data ======================= The F2PY interface to Fortran 90 module data is similar to Fortran 77 common blocks. -.. example:: - - Consider the following `Fortran 90 code`__ +Consider the following Fortran 90 code: .. include:: moddata.f90 :literal: - and wrap it using ``f2py -c -m moddata moddata.f90``. - - __ moddata.f90 +and wrap it using ``f2py -c -m moddata moddata.f90``. - In Python: +In Python: .. include:: moddata_session.dat :literal: + Allocatable arrays ------------------- F2PY has basic support for Fortran 90 module allocatable arrays. -.. example:: - - Consider the following `Fortran 90 code`__ +Consider the following Fortran 90 code: .. include:: allocarr.f90 :literal: - and wrap it using ``f2py -c -m allocarr allocarr.f90``. - - __ allocarr.f90 +and wrap it using ``f2py -c -m allocarr allocarr.f90``. - In Python: +In Python: .. include:: allocarr_session.dat :literal: diff --git a/doc/source/f2py/usage.rst b/doc/source/f2py/usage.rst index 2f9017faa..a6f093154 100644 --- a/doc/source/f2py/usage.rst +++ b/doc/source/f2py/usage.rst @@ -183,7 +183,7 @@ Other options: without the ``-h`` switch. ``--build-dir <dirname>`` All F2PY generated files are created in ``<dirname>``. Default is - ``tempfile.mktemp()``. + ``tempfile.mkdtemp()``. ``--quiet`` Run quietly. ``--verbose`` diff --git a/doc/source/neps/datetime-proposal.rst b/doc/source/neps/datetime-proposal.rst new file mode 100644 index 000000000..05f0182b7 --- /dev/null +++ b/doc/source/neps/datetime-proposal.rst @@ -0,0 +1 @@ +.. include:: ../../neps/datetime-proposal.rst diff --git a/doc/source/neps/datetime-proposal3.rst b/doc/source/neps/datetime-proposal3.rst new file mode 100644 index 000000000..fa9102a96 --- /dev/null +++ b/doc/source/neps/datetime-proposal3.rst @@ -0,0 +1 @@ +.. include:: ../../neps/datetime-proposal3.rst diff --git a/doc/source/neps/deferred-ufunc-evaluation.rst b/doc/source/neps/deferred-ufunc-evaluation.rst new file mode 100644 index 000000000..b4a7a457d --- /dev/null +++ b/doc/source/neps/deferred-ufunc-evaluation.rst @@ -0,0 +1 @@ +.. include:: ../../neps/deferred-ufunc-evaluation.rst diff --git a/doc/source/neps/generalized-ufuncs.rst b/doc/source/neps/generalized-ufuncs.rst new file mode 100644 index 000000000..8b28f0224 --- /dev/null +++ b/doc/source/neps/generalized-ufuncs.rst @@ -0,0 +1 @@ +.. include:: ../../neps/generalized-ufuncs.rst diff --git a/doc/source/neps/groupby_additions.rst b/doc/source/neps/groupby_additions.rst new file mode 100644 index 000000000..61abc951e --- /dev/null +++ b/doc/source/neps/groupby_additions.rst @@ -0,0 +1 @@ +.. include:: ../../neps/groupby_additions.rst diff --git a/doc/source/neps/index.rst b/doc/source/neps/index.rst new file mode 100644 index 000000000..94cf563a4 --- /dev/null +++ b/doc/source/neps/index.rst @@ -0,0 +1,37 @@ +=========================== +Numpy Enhancement Proposals +=========================== + +Numpy Enhancement Proposals (NEPs) describe proposed changes to Numpy. +NEPs are modeled on Python Enhancement Proposals (PEPs), and are typically +written up when large changes to Numpy are proposed. + +This page provides an overview of all NEPs, making only a distinction between +the ones that have been implemented and those that have not been implemented. + +Implemented NEPs +---------------- + +.. toctree:: + :maxdepth: 1 + + ufunc-overrides + generalized-ufuncs + new-iterator-ufunc + npy-format + +Other NEPs +---------- + +.. toctree:: + :maxdepth: 1 + + missing-data + math_config_clean + groupby_additions + warnfix + newbugtracker + deferred-ufunc-evaluation + structured_array_extensions + datetime-proposal + datetime-proposal3 diff --git a/doc/source/neps/math_config_clean.rst b/doc/source/neps/math_config_clean.rst new file mode 100644 index 000000000..25b340e51 --- /dev/null +++ b/doc/source/neps/math_config_clean.rst @@ -0,0 +1 @@ +.. include:: ../../neps/math_config_clean.rst diff --git a/doc/source/neps/missing-data.rst b/doc/source/neps/missing-data.rst new file mode 100644 index 000000000..f9899f1b0 --- /dev/null +++ b/doc/source/neps/missing-data.rst @@ -0,0 +1 @@ +.. include:: ../../neps/missing-data.rst diff --git a/doc/source/neps/new-iterator-ufunc.rst b/doc/source/neps/new-iterator-ufunc.rst new file mode 100644 index 000000000..7e06aa8ae --- /dev/null +++ b/doc/source/neps/new-iterator-ufunc.rst @@ -0,0 +1 @@ +.. include:: ../../neps/new-iterator-ufunc.rst diff --git a/doc/source/neps/newbugtracker.rst b/doc/source/neps/newbugtracker.rst new file mode 100644 index 000000000..70ea21f8c --- /dev/null +++ b/doc/source/neps/newbugtracker.rst @@ -0,0 +1 @@ +.. include:: ../../neps/newbugtracker.rst diff --git a/doc/source/neps/npy-format.rst b/doc/source/neps/npy-format.rst new file mode 100644 index 000000000..bd1f2bb5c --- /dev/null +++ b/doc/source/neps/npy-format.rst @@ -0,0 +1 @@ +.. include:: ../../neps/npy-format.rst diff --git a/doc/source/neps/structured_array_extensions.rst b/doc/source/neps/structured_array_extensions.rst new file mode 100644 index 000000000..341e6c955 --- /dev/null +++ b/doc/source/neps/structured_array_extensions.rst @@ -0,0 +1 @@ +.. include:: ../../neps/structured_array_extensions.rst diff --git a/doc/source/neps/ufunc-overrides.rst b/doc/source/neps/ufunc-overrides.rst new file mode 100644 index 000000000..2e293ec44 --- /dev/null +++ b/doc/source/neps/ufunc-overrides.rst @@ -0,0 +1 @@ +.. include:: ../../neps/ufunc-overrides.rst diff --git a/doc/source/neps/warnfix.rst b/doc/source/neps/warnfix.rst new file mode 100644 index 000000000..1b9b1b87b --- /dev/null +++ b/doc/source/neps/warnfix.rst @@ -0,0 +1 @@ +.. include:: ../../neps/warnfix.rst 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. diff --git a/doc/source/user/c-info.how-to-extend.rst b/doc/source/user/c-info.how-to-extend.rst index 5901ce3e3..db6c8e118 100644 --- a/doc/source/user/c-info.how-to-extend.rst +++ b/doc/source/user/c-info.how-to-extend.rst @@ -255,7 +255,7 @@ Reference counting The biggest difficulty when writing extension modules is reference counting. It is an important reason for the popularity of f2py, weave, -pyrex, ctypes, etc.... If you mis-handle reference counts you can get +Cython, ctypes, etc.... If you mis-handle reference counts you can get problems from memory-leaks to segmentation faults. The only strategy I know of to handle reference counts correctly is blood, sweat, and tears. First, you force it into your head that every Python variable diff --git a/doc/source/user/c-info.python-as-glue.rst b/doc/source/user/c-info.python-as-glue.rst index 6ce266859..985d478e0 100644 --- a/doc/source/user/c-info.python-as-glue.rst +++ b/doc/source/user/c-info.python-as-glue.rst @@ -1385,7 +1385,7 @@ Simplified Wrapper and Interface Generator (SWIG) is an old and fairly stable method for wrapping C/C++-libraries to a large variety of other languages. It does not specifically understand NumPy arrays but can be made useable with NumPy through the use of typemaps. There are some -sample typemaps in the numpy/doc/swig directory under numpy.i along +sample typemaps in the numpy/tools/swig directory under numpy.i together with an example module that makes use of them. SWIG excels at wrapping large C/C++ libraries because it can (almost) parse their headers and auto-produce an interface. Technically, you need to generate a ``.i`` diff --git a/doc/source/user/install.rst b/doc/source/user/install.rst index 18e036ab0..9d6f61e65 100644 --- a/doc/source/user/install.rst +++ b/doc/source/user/install.rst @@ -11,9 +11,9 @@ installable binary package for your operating system. Windows ------- -Good solutions for Windows are, The Enthought Python Distribution `(EPD) -<http://www.enthought.com/products/epd.php>`_ (which provides binary -installers for Windows, OS X and Redhat) and `Python (x, y) +Good solutions for Windows are, `Enthought Canopy +<https://www.enthought.com/products/canopy/>`_ (which provides binary +installers for Windows, OS X and Linux) and `Python (x, y) <http://www.pythonxy.com>`_. Both of these packages include Python, NumPy and many additional packages. diff --git a/doc/source/user/whatisnumpy.rst b/doc/source/user/whatisnumpy.rst index 1c3f96b8b..cd74a8de3 100644 --- a/doc/source/user/whatisnumpy.rst +++ b/doc/source/user/whatisnumpy.rst @@ -86,14 +86,14 @@ code. In NumPy c = a * b does what the earlier examples do, at near-C speeds, but with the code -simplicity we expect from something based on Python (indeed, the NumPy -idiom is even simpler!). This last example illustrates two of NumPy's +simplicity we expect from something based on Python. Indeed, the NumPy +idiom is even simpler! This last example illustrates two of NumPy's features which are the basis of much of its power: vectorization and broadcasting. Vectorization describes the absence of any explicit looping, indexing, etc., in the code - these things are taking place, of course, just -"behind the scenes" (in optimized, pre-compiled C code). Vectorized +"behind the scenes" in optimized, pre-compiled C code. Vectorized code has many advantages, among which are: - vectorized code is more concise and easier to read @@ -104,25 +104,25 @@ code has many advantages, among which are: (making it easier, typically, to correctly code mathematical constructs) -- vectorization results in more "Pythonic" code (without - vectorization, our code would still be littered with inefficient and +- vectorization results in more "Pythonic" code. Without + vectorization, our code would be littered with inefficient and difficult to read ``for`` loops. Broadcasting is the term used to describe the implicit element-by-element behavior of operations; generally speaking, in -NumPy all operations (i.e., not just arithmetic operations, but -logical, bit-wise, functional, etc.) behave in this implicit +NumPy all operations, not just arithmetic operations, but +logical, bit-wise, functional, etc., behave in this implicit element-by-element fashion, i.e., they broadcast. Moreover, in the example above, ``a`` and ``b`` could be multidimensional arrays of the same shape, or a scalar and an array, or even two arrays of with -different shapes. Provided that the smaller array is "expandable" to +different shapes, provided that the smaller array is "expandable" to the shape of the larger in such a way that the resulting broadcast is -unambiguous (for detailed "rules" of broadcasting see -`numpy.doc.broadcasting`). +unambiguous. For detailed "rules" of broadcasting see +`numpy.doc.broadcasting`. NumPy fully supports an object-oriented approach, starting, once again, with `ndarray`. For example, `ndarray` is a class, possessing -numerous methods and attributes. Many, of it's methods mirror -functions in the outer-most NumPy namespace, giving the programmer has +numerous methods and attributes. Many of its methods mirror +functions in the outer-most NumPy namespace, giving the programmer complete freedom to code in whichever paradigm she prefers and/or which seems most appropriate to the task at hand. |