tmp
/
pip-install-ghxuqwgs
/numpy_78e94bf2b6094bf9a1f3d92042f9bf46
/doc
/source
/reference
/arrays.indexing.rst
| .. _arrays.indexing: | |
| Indexing | |
| ======== | |
| .. sectionauthor:: adapted from "Guide to Numpy" by Travis E. Oliphant | |
| .. currentmodule:: numpy | |
| .. index:: indexing, slicing | |
| <ndarray>` can be indexed using the standard Python | |
| ``x[obj]`` syntax, where *x* is the array and *obj* the selection. | |
| There are three kinds of indexing available: record access, basic | |
| slicing, advanced indexing. Which one occurs depends on *obj*. | |
| .. note:: | |
| In Python, ``x[(exp1, exp2, ..., expN)]`` is equivalent to | |
| ``x[exp1, exp2, ..., expN]``; the latter is just syntactic sugar | |
| for the former. | |
| 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 | |
| (constructed by ``start:stop:step`` notation inside of brackets), an | |
| 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 non-ndarray sequence (such as a :class:`list`) containing :class:`slice` | |
| objects, the :const:`Ellipsis` object, or the :const:`newaxis` object, | |
| but not for integer arrays or other embedded sequences. | |
| .. index:: | |
| triple: ndarray; special methods; getslice | |
| triple: ndarray; special methods; setslice | |
| single: ellipsis | |
| single: newaxis | |
| The simplest case of indexing with *N* integers returns an :ref:`array | |
| 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 | |
| :math:`n_i < 0`, it means :math:`n_i + d_i`). | |
| All arrays generated by basic slicing are always :term:`views <view>` | |
| of the original array. | |
| The standard rules of sequence slicing apply to basic slicing on a | |
| per-dimension basis (including using a step index). Some useful | |
| concepts to remember include: | |
| - The basic slice syntax is ``i:j:k`` where *i* is the starting index, | |
| *j* is the stopping index, and *k* is the step (:math:`k\neq0`). | |
| This selects the *m* elements (in the corresponding dimension) with | |
| index values *i*, *i + k*, ..., *i + (m - 1) k* where | |
| :math:`m = q + (r\neq0)` and *q* and *r* are the quotient and remainder | |
| obtained by dividing *j - i* by *k*: *j - i = q k + r*, so that | |
| *i + (m - 1) k < j*. | |
| .. admonition:: Example | |
| >>> x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) | |
| >>> x[1:7:2] | |
| array([1, 3, 5]) | |
| - Negative *i* and *j* are interpreted as *n + i* and *n + j* where | |
| *n* is the number of elements in the corresponding dimension. | |
| Negative *k* makes stepping go towards smaller indices. | |
| .. admonition:: Example | |
| >>> x[-2:10] | |
| array([8, 9]) | |
| >>> x[-3:3:-1] | |
| array([7, 6, 5, 4]) | |
| - 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 - 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. | |
| .. admonition:: Example | |
| >>> x[5:] | |
| array([5, 6, 7, 8, 9]) | |
| - If the number of objects in the selection tuple is less than | |
| *N* , then ``:`` is assumed for any subsequent dimensions. | |
| .. admonition:: Example | |
| >>> x = np.array([[[1],[2],[3]], [[4],[5],[6]]]) | |
| >>> x.shape | |
| (2, 3, 1) | |
| >>> x[1:2] | |
| array([[[4], | |
| [5], | |
| [6]]]) | |
| - :const:`Ellipsis` expand to the number of ``:`` objects needed to | |
| make a selection tuple of the same length as ``x.ndim``. There may | |
| only be a single ellipsis present. | |
| .. admonition:: Example | |
| >>> x[...,0] | |
| array([[1, 2, 3], | |
| [4, 5, 6]]) | |
| - Each :const:`newaxis` object in the selection tuple serves to expand | |
| the dimensions of the resulting selection by one unit-length | |
| dimension. The added dimension is the position of the :const:`newaxis` | |
| object in the selection tuple. | |
| .. admonition:: Example | |
| >>> x[:,np.newaxis,:,:].shape | |
| (2, 1, 3, 1) | |
| - An integer, *i*, returns the same values as ``i:i+1`` | |
| **except** the dimensionality of the returned object is reduced by | |
| 1. In particular, a selection tuple with the *p*-th | |
| element an integer (and all other entries ``:``) returns the | |
| corresponding sub-array with dimension *N - 1*. If *N = 1* | |
| then the returned object is an array scalar. These objects are | |
| explained in :ref:`arrays.scalars`. | |
| - If the selection tuple has all entries ``:`` except the | |
| *p*-th entry which is a slice object ``i:j:k``, | |
| then the returned array has dimension *N* formed by | |
| concatenating the sub-arrays returned by integer indexing of | |
| elements *i*, *i+k*, ..., *i + (m - 1) k < j*, | |
| - Basic slicing with more than one non-``:`` entry in the slicing | |
| tuple, acts like repeated application of slicing using a single | |
| non-``:`` entry, where the non-``:`` entries are successively taken | |
| (with all other non-``:`` entries replaced by ``:``). Thus, | |
| ``x[ind1,...,ind2,:]`` acts like ``x[ind1][...,ind2,:]`` under basic | |
| 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 | |
| ``x[obj] = value`` must be (broadcastable) to the same shape as | |
| ``x[obj]``. | |
| .. index:: | |
| pair: ndarray; view | |
| .. note:: | |
| Remember that a slicing tuple can always be constructed as *obj* | |
| and used in the ``x[obj]`` notation. Slice objects can be used in | |
| the construction in place of the ``[start:stop:step]`` | |
| notation. For example, ``x[1:10:5,::-1]`` can also be implemented | |
| as ``obj = (slice(1,10,5), slice(None,None,-1)); x[obj]`` . This | |
| can be useful for constructing generic code that works on arrays | |
| of arbitrary dimension. | |
| .. data:: 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 is triggered when the selection object, *obj*, is a | |
| non-tuple sequence object, an :class:`ndarray` (of data type integer or bool), | |
| or a tuple with at least one sequence object or ndarray (of data type | |
| integer or bool). There are two types of advanced indexing: integer | |
| and Boolean. | |
| Advanced indexing always returns a *copy* of the data (contrast with | |
| basic slicing that returns a :term:`view`). | |
| .. warning:: | |
| 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. | |
| Also recognize that ``x[[1,2,3]]`` will trigger advanced indexing, | |
| whereas ``x[[1,2,slice(None)]]`` will trigger basic slicing. | |
| Integer array indexing | |
| ^^^^^^^^^^^^^^^^^^^^^^ | |
| 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. | |
| Purely integer array indexing | |
| """"""""""""""""""""""""""""" | |
| 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. | |
| Advanced indexes always are :ref:`broadcast<ufuncs.broadcasting>` and | |
| iterated as *one*:: | |
| result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M], | |
| ..., ind_N[i_1, ..., i_M]] | |
| Note that the result shape is identical to the (broadcast) indexing array | |
| shapes ``ind_1, ..., ind_N``. | |
| .. admonition:: Example | |
| 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: | |
| >>> x = np.array([[1, 2], [3, 4], [5, 6]]) | |
| >>> x[[0, 1, 2], [0, 1, 0]] | |
| array([1, 4, 5]) | |
| 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 | |
| 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 | |
| >>> 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 | |
| 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 array indexing | |
| ^^^^^^^^^^^^^^^^^^^^^^ | |
| This advanced indexing occurs when obj is an array object of Boolean | |
| 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*. However, it is | |
| faster when ``obj.shape == x.shape``. | |
| 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. If *obj* is smaller | |
| than *x* it is identical to filling it with :const:`False`. | |
| .. admonition:: Example | |
| 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: | |
| >>> x = np.array([[1., 2.], [np.nan, 3.], [np.nan, np.nan]]) | |
| >>> x[~np.isnan(x)] | |
| array([ 1., 2., 3.]) | |
| 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 | |
| <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 | |
| ------------- | |
| .. seealso:: :ref:`arrays.dtypes`, :ref:`arrays.scalars` | |
| If the :class:`ndarray` object is a record array, *i.e.* its data type | |
| is a :term:`record` data type, the :term:`fields <field>` of the array | |
| can be accessed by indexing the array with strings, dictionary-like. | |
| Indexing ``x['field-name']`` returns a new :term:`view` to the array, | |
| which is of the same shape as *x* (except when the field is a | |
| sub-array) but of data type ``x.dtype['field-name']`` and contains | |
| only the part of the data in the specified field. Also record array | |
| scalars can be "indexed" this way. | |
| Indexing into a record array can also be done with a list of field names, | |
| *e.g.* ``x[['field-name1','field-name2']]``. Currently this returns a new | |
| array containing a copy of the values in the fields specified in the list. | |
| As of NumPy 1.7, returning a copy is being deprecated in favor of returning | |
| a view. A copy will continue to be returned for now, but a FutureWarning | |
| will be issued when writing to the copy. If you depend on the current | |
| behavior, then we suggest copying the returned array explicitly, i.e. use | |
| x[['field-name1','field-name2']].copy(). This will work with both past and | |
| future versions of NumPy. | |
| If the accessed field is a sub-array, the dimensions of the sub-array | |
| are appended to the shape of the result. | |
| .. admonition:: Example | |
| >>> x = np.zeros((2,2), dtype=[('a', np.int32), ('b', np.float64, (3,3))]) | |
| >>> x['a'].shape | |
| (2, 2) | |
| >>> x['a'].dtype | |
| dtype('int32') | |
| >>> x['b'].shape | |
| (2, 2, 3, 3) | |
| >>> x['b'].dtype | |
| dtype('float64') | |
| Flat Iterator indexing | |
| ---------------------- | |
| <ndarray.flat>` returns an iterator that will iterate | |
| over the entire array (in C-contiguous style with the last index | |
| varying the fastest). This iterator object can also be indexed using | |
| basic slicing or advanced indexing as long as the selection object is | |
| not a tuple. This should be clear from the fact that :attr:`x.flat | |
| <ndarray.flat>` is a 1-dimensional view. It can be used for integer | |
| indexing with 1-dimensional C-style-flat indices. The shape of any | |
| returned array is therefore the shape of the integer indexing object. | |
| .. index:: | |
| single: indexing | |
| single: ndarray | |