123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059 |
- """ Basic functions for manipulating 2d arrays
- """
- import functools
- from numpy.core.numeric import (
- asanyarray, arange, zeros, greater_equal, multiply, ones,
- asarray, where, int8, int16, int32, int64, intp, empty, promote_types,
- diagonal, nonzero, indices
- )
- from numpy.core.overrides import set_array_function_like_doc, set_module
- from numpy.core import overrides
- from numpy.core import iinfo
- from numpy.lib.stride_tricks import broadcast_to
- __all__ = [
- 'diag', 'diagflat', 'eye', 'fliplr', 'flipud', 'tri', 'triu',
- 'tril', 'vander', 'histogram2d', 'mask_indices', 'tril_indices',
- 'tril_indices_from', 'triu_indices', 'triu_indices_from', ]
- array_function_dispatch = functools.partial(
- overrides.array_function_dispatch, module='numpy')
- i1 = iinfo(int8)
- i2 = iinfo(int16)
- i4 = iinfo(int32)
- def _min_int(low, high):
- """ get small int that fits the range """
- if high <= i1.max and low >= i1.min:
- return int8
- if high <= i2.max and low >= i2.min:
- return int16
- if high <= i4.max and low >= i4.min:
- return int32
- return int64
- def _flip_dispatcher(m):
- return (m,)
- @array_function_dispatch(_flip_dispatcher)
- def fliplr(m):
- """
- Reverse the order of elements along axis 1 (left/right).
- For a 2-D array, this flips the entries in each row in the left/right
- direction. Columns are preserved, but appear in a different order than
- before.
- Parameters
- ----------
- m : array_like
- Input array, must be at least 2-D.
- Returns
- -------
- f : ndarray
- A view of `m` with the columns reversed. Since a view
- is returned, this operation is :math:`\\mathcal O(1)`.
- See Also
- --------
- flipud : Flip array in the up/down direction.
- flip : Flip array in one or more dimesions.
- rot90 : Rotate array counterclockwise.
- Notes
- -----
- Equivalent to ``m[:,::-1]`` or ``np.flip(m, axis=1)``.
- Requires the array to be at least 2-D.
- Examples
- --------
- >>> A = np.diag([1.,2.,3.])
- >>> A
- array([[1., 0., 0.],
- [0., 2., 0.],
- [0., 0., 3.]])
- >>> np.fliplr(A)
- array([[0., 0., 1.],
- [0., 2., 0.],
- [3., 0., 0.]])
- >>> A = np.random.randn(2,3,5)
- >>> np.all(np.fliplr(A) == A[:,::-1,...])
- True
- """
- m = asanyarray(m)
- if m.ndim < 2:
- raise ValueError("Input must be >= 2-d.")
- return m[:, ::-1]
- @array_function_dispatch(_flip_dispatcher)
- def flipud(m):
- """
- Reverse the order of elements along axis 0 (up/down).
- For a 2-D array, this flips the entries in each column in the up/down
- direction. Rows are preserved, but appear in a different order than before.
- Parameters
- ----------
- m : array_like
- Input array.
- Returns
- -------
- out : array_like
- A view of `m` with the rows reversed. Since a view is
- returned, this operation is :math:`\\mathcal O(1)`.
- See Also
- --------
- fliplr : Flip array in the left/right direction.
- flip : Flip array in one or more dimesions.
- rot90 : Rotate array counterclockwise.
- Notes
- -----
- Equivalent to ``m[::-1, ...]`` or ``np.flip(m, axis=0)``.
- Requires the array to be at least 1-D.
- Examples
- --------
- >>> A = np.diag([1.0, 2, 3])
- >>> A
- array([[1., 0., 0.],
- [0., 2., 0.],
- [0., 0., 3.]])
- >>> np.flipud(A)
- array([[0., 0., 3.],
- [0., 2., 0.],
- [1., 0., 0.]])
- >>> A = np.random.randn(2,3,5)
- >>> np.all(np.flipud(A) == A[::-1,...])
- True
- >>> np.flipud([1,2])
- array([2, 1])
- """
- m = asanyarray(m)
- if m.ndim < 1:
- raise ValueError("Input must be >= 1-d.")
- return m[::-1, ...]
- def _eye_dispatcher(N, M=None, k=None, dtype=None, order=None, *, like=None):
- return (like,)
- @set_array_function_like_doc
- @set_module('numpy')
- def eye(N, M=None, k=0, dtype=float, order='C', *, like=None):
- """
- Return a 2-D array with ones on the diagonal and zeros elsewhere.
- Parameters
- ----------
- N : int
- Number of rows in the output.
- M : int, optional
- Number of columns in the output. If None, defaults to `N`.
- k : int, optional
- Index of the diagonal: 0 (the default) refers to the main diagonal,
- a positive value refers to an upper diagonal, and a negative value
- to a lower diagonal.
- dtype : data-type, optional
- Data-type of the returned array.
- order : {'C', 'F'}, optional
- Whether the output should be stored in row-major (C-style) or
- column-major (Fortran-style) order in memory.
- .. versionadded:: 1.14.0
- ${ARRAY_FUNCTION_LIKE}
- .. versionadded:: 1.20.0
- Returns
- -------
- I : ndarray of shape (N,M)
- An array where all elements are equal to zero, except for the `k`-th
- diagonal, whose values are equal to one.
- See Also
- --------
- identity : (almost) equivalent function
- diag : diagonal 2-D array from a 1-D array specified by the user.
- Examples
- --------
- >>> np.eye(2, dtype=int)
- array([[1, 0],
- [0, 1]])
- >>> np.eye(3, k=1)
- array([[0., 1., 0.],
- [0., 0., 1.],
- [0., 0., 0.]])
- """
- if like is not None:
- return _eye_with_like(N, M=M, k=k, dtype=dtype, order=order, like=like)
- if M is None:
- M = N
- m = zeros((N, M), dtype=dtype, order=order)
- if k >= M:
- return m
- if k >= 0:
- i = k
- else:
- i = (-k) * M
- m[:M-k].flat[i::M+1] = 1
- return m
- _eye_with_like = array_function_dispatch(
- _eye_dispatcher
- )(eye)
- def _diag_dispatcher(v, k=None):
- return (v,)
- @array_function_dispatch(_diag_dispatcher)
- def diag(v, k=0):
- """
- Extract a diagonal or construct a diagonal array.
- See the more detailed documentation for ``numpy.diagonal`` if you use this
- function to extract a diagonal and wish to write to the resulting array;
- whether it returns a copy or a view depends on what version of numpy you
- are using.
- Parameters
- ----------
- v : array_like
- If `v` is a 2-D array, return a copy of its `k`-th diagonal.
- If `v` is a 1-D array, return a 2-D array with `v` on the `k`-th
- diagonal.
- k : int, optional
- Diagonal in question. The default is 0. Use `k>0` for diagonals
- above the main diagonal, and `k<0` for diagonals below the main
- diagonal.
- Returns
- -------
- out : ndarray
- The extracted diagonal or constructed diagonal array.
- See Also
- --------
- diagonal : Return specified diagonals.
- diagflat : Create a 2-D array with the flattened input as a diagonal.
- trace : Sum along diagonals.
- triu : Upper triangle of an array.
- tril : Lower triangle of an array.
- Examples
- --------
- >>> x = np.arange(9).reshape((3,3))
- >>> x
- array([[0, 1, 2],
- [3, 4, 5],
- [6, 7, 8]])
- >>> np.diag(x)
- array([0, 4, 8])
- >>> np.diag(x, k=1)
- array([1, 5])
- >>> np.diag(x, k=-1)
- array([3, 7])
- >>> np.diag(np.diag(x))
- array([[0, 0, 0],
- [0, 4, 0],
- [0, 0, 8]])
- """
- v = asanyarray(v)
- s = v.shape
- if len(s) == 1:
- n = s[0]+abs(k)
- res = zeros((n, n), v.dtype)
- if k >= 0:
- i = k
- else:
- i = (-k) * n
- res[:n-k].flat[i::n+1] = v
- return res
- elif len(s) == 2:
- return diagonal(v, k)
- else:
- raise ValueError("Input must be 1- or 2-d.")
- @array_function_dispatch(_diag_dispatcher)
- def diagflat(v, k=0):
- """
- Create a two-dimensional array with the flattened input as a diagonal.
- Parameters
- ----------
- v : array_like
- Input data, which is flattened and set as the `k`-th
- diagonal of the output.
- k : int, optional
- Diagonal to set; 0, the default, corresponds to the "main" diagonal,
- a positive (negative) `k` giving the number of the diagonal above
- (below) the main.
- Returns
- -------
- out : ndarray
- The 2-D output array.
- See Also
- --------
- diag : MATLAB work-alike for 1-D and 2-D arrays.
- diagonal : Return specified diagonals.
- trace : Sum along diagonals.
- Examples
- --------
- >>> np.diagflat([[1,2], [3,4]])
- array([[1, 0, 0, 0],
- [0, 2, 0, 0],
- [0, 0, 3, 0],
- [0, 0, 0, 4]])
- >>> np.diagflat([1,2], 1)
- array([[0, 1, 0],
- [0, 0, 2],
- [0, 0, 0]])
- """
- try:
- wrap = v.__array_wrap__
- except AttributeError:
- wrap = None
- v = asarray(v).ravel()
- s = len(v)
- n = s + abs(k)
- res = zeros((n, n), v.dtype)
- if (k >= 0):
- i = arange(0, n-k, dtype=intp)
- fi = i+k+i*n
- else:
- i = arange(0, n+k, dtype=intp)
- fi = i+(i-k)*n
- res.flat[fi] = v
- if not wrap:
- return res
- return wrap(res)
- def _tri_dispatcher(N, M=None, k=None, dtype=None, *, like=None):
- return (like,)
- @set_array_function_like_doc
- @set_module('numpy')
- def tri(N, M=None, k=0, dtype=float, *, like=None):
- """
- An array with ones at and below the given diagonal and zeros elsewhere.
- Parameters
- ----------
- N : int
- Number of rows in the array.
- M : int, optional
- Number of columns in the array.
- By default, `M` is taken equal to `N`.
- k : int, optional
- The sub-diagonal at and below which the array is filled.
- `k` = 0 is the main diagonal, while `k` < 0 is below it,
- and `k` > 0 is above. The default is 0.
- dtype : dtype, optional
- Data type of the returned array. The default is float.
- ${ARRAY_FUNCTION_LIKE}
- .. versionadded:: 1.20.0
- Returns
- -------
- tri : ndarray of shape (N, M)
- Array with its lower triangle filled with ones and zero elsewhere;
- in other words ``T[i,j] == 1`` for ``j <= i + k``, 0 otherwise.
- Examples
- --------
- >>> np.tri(3, 5, 2, dtype=int)
- array([[1, 1, 1, 0, 0],
- [1, 1, 1, 1, 0],
- [1, 1, 1, 1, 1]])
- >>> np.tri(3, 5, -1)
- array([[0., 0., 0., 0., 0.],
- [1., 0., 0., 0., 0.],
- [1., 1., 0., 0., 0.]])
- """
- if like is not None:
- return _tri_with_like(N, M=M, k=k, dtype=dtype, like=like)
- if M is None:
- M = N
- m = greater_equal.outer(arange(N, dtype=_min_int(0, N)),
- arange(-k, M-k, dtype=_min_int(-k, M - k)))
- # Avoid making a copy if the requested type is already bool
- m = m.astype(dtype, copy=False)
- return m
- _tri_with_like = array_function_dispatch(
- _tri_dispatcher
- )(tri)
- def _trilu_dispatcher(m, k=None):
- return (m,)
- @array_function_dispatch(_trilu_dispatcher)
- def tril(m, k=0):
- """
- Lower triangle of an array.
- Return a copy of an array with elements above the `k`-th diagonal zeroed.
- Parameters
- ----------
- m : array_like, shape (M, N)
- Input array.
- k : int, optional
- Diagonal above which to zero elements. `k = 0` (the default) is the
- main diagonal, `k < 0` is below it and `k > 0` is above.
- Returns
- -------
- tril : ndarray, shape (M, N)
- Lower triangle of `m`, of same shape and data-type as `m`.
- See Also
- --------
- triu : same thing, only for the upper triangle
- Examples
- --------
- >>> np.tril([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
- array([[ 0, 0, 0],
- [ 4, 0, 0],
- [ 7, 8, 0],
- [10, 11, 12]])
- """
- m = asanyarray(m)
- mask = tri(*m.shape[-2:], k=k, dtype=bool)
- return where(mask, m, zeros(1, m.dtype))
- @array_function_dispatch(_trilu_dispatcher)
- def triu(m, k=0):
- """
- Upper triangle of an array.
- Return a copy of an array with the elements below the `k`-th diagonal
- zeroed.
- Please refer to the documentation for `tril` for further details.
- See Also
- --------
- tril : lower triangle of an array
- Examples
- --------
- >>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
- array([[ 1, 2, 3],
- [ 4, 5, 6],
- [ 0, 8, 9],
- [ 0, 0, 12]])
- """
- m = asanyarray(m)
- mask = tri(*m.shape[-2:], k=k-1, dtype=bool)
- return where(mask, zeros(1, m.dtype), m)
- def _vander_dispatcher(x, N=None, increasing=None):
- return (x,)
- # Originally borrowed from John Hunter and matplotlib
- @array_function_dispatch(_vander_dispatcher)
- def vander(x, N=None, increasing=False):
- """
- Generate a Vandermonde matrix.
- The columns of the output matrix are powers of the input vector. The
- order of the powers is determined by the `increasing` boolean argument.
- Specifically, when `increasing` is False, the `i`-th output column is
- the input vector raised element-wise to the power of ``N - i - 1``. Such
- a matrix with a geometric progression in each row is named for Alexandre-
- Theophile Vandermonde.
- Parameters
- ----------
- x : array_like
- 1-D input array.
- N : int, optional
- Number of columns in the output. If `N` is not specified, a square
- array is returned (``N = len(x)``).
- increasing : bool, optional
- Order of the powers of the columns. If True, the powers increase
- from left to right, if False (the default) they are reversed.
- .. versionadded:: 1.9.0
- Returns
- -------
- out : ndarray
- Vandermonde matrix. If `increasing` is False, the first column is
- ``x^(N-1)``, the second ``x^(N-2)`` and so forth. If `increasing` is
- True, the columns are ``x^0, x^1, ..., x^(N-1)``.
- See Also
- --------
- polynomial.polynomial.polyvander
- Examples
- --------
- >>> x = np.array([1, 2, 3, 5])
- >>> N = 3
- >>> np.vander(x, N)
- array([[ 1, 1, 1],
- [ 4, 2, 1],
- [ 9, 3, 1],
- [25, 5, 1]])
- >>> np.column_stack([x**(N-1-i) for i in range(N)])
- array([[ 1, 1, 1],
- [ 4, 2, 1],
- [ 9, 3, 1],
- [25, 5, 1]])
- >>> x = np.array([1, 2, 3, 5])
- >>> np.vander(x)
- array([[ 1, 1, 1, 1],
- [ 8, 4, 2, 1],
- [ 27, 9, 3, 1],
- [125, 25, 5, 1]])
- >>> np.vander(x, increasing=True)
- array([[ 1, 1, 1, 1],
- [ 1, 2, 4, 8],
- [ 1, 3, 9, 27],
- [ 1, 5, 25, 125]])
- The determinant of a square Vandermonde matrix is the product
- of the differences between the values of the input vector:
- >>> np.linalg.det(np.vander(x))
- 48.000000000000043 # may vary
- >>> (5-3)*(5-2)*(5-1)*(3-2)*(3-1)*(2-1)
- 48
- """
- x = asarray(x)
- if x.ndim != 1:
- raise ValueError("x must be a one-dimensional array or sequence.")
- if N is None:
- N = len(x)
- v = empty((len(x), N), dtype=promote_types(x.dtype, int))
- tmp = v[:, ::-1] if not increasing else v
- if N > 0:
- tmp[:, 0] = 1
- if N > 1:
- tmp[:, 1:] = x[:, None]
- multiply.accumulate(tmp[:, 1:], out=tmp[:, 1:], axis=1)
- return v
- def _histogram2d_dispatcher(x, y, bins=None, range=None, normed=None,
- weights=None, density=None):
- yield x
- yield y
- # This terrible logic is adapted from the checks in histogram2d
- try:
- N = len(bins)
- except TypeError:
- N = 1
- if N == 2:
- yield from bins # bins=[x, y]
- else:
- yield bins
- yield weights
- @array_function_dispatch(_histogram2d_dispatcher)
- def histogram2d(x, y, bins=10, range=None, normed=None, weights=None,
- density=None):
- """
- Compute the bi-dimensional histogram of two data samples.
- Parameters
- ----------
- x : array_like, shape (N,)
- An array containing the x coordinates of the points to be
- histogrammed.
- y : array_like, shape (N,)
- An array containing the y coordinates of the points to be
- histogrammed.
- bins : int or array_like or [int, int] or [array, array], optional
- The bin specification:
- * If int, the number of bins for the two dimensions (nx=ny=bins).
- * If array_like, the bin edges for the two dimensions
- (x_edges=y_edges=bins).
- * If [int, int], the number of bins in each dimension
- (nx, ny = bins).
- * If [array, array], the bin edges in each dimension
- (x_edges, y_edges = bins).
- * A combination [int, array] or [array, int], where int
- is the number of bins and array is the bin edges.
- range : array_like, shape(2,2), optional
- The leftmost and rightmost edges of the bins along each dimension
- (if not specified explicitly in the `bins` parameters):
- ``[[xmin, xmax], [ymin, ymax]]``. All values outside of this range
- will be considered outliers and not tallied in the histogram.
- density : bool, optional
- If False, the default, returns the number of samples in each bin.
- If True, returns the probability *density* function at the bin,
- ``bin_count / sample_count / bin_area``.
- normed : bool, optional
- An alias for the density argument that behaves identically. To avoid
- confusion with the broken normed argument to `histogram`, `density`
- should be preferred.
- weights : array_like, shape(N,), optional
- An array of values ``w_i`` weighing each sample ``(x_i, y_i)``.
- Weights are normalized to 1 if `normed` is True. If `normed` is
- False, the values of the returned histogram are equal to the sum of
- the weights belonging to the samples falling into each bin.
- Returns
- -------
- H : ndarray, shape(nx, ny)
- The bi-dimensional histogram of samples `x` and `y`. Values in `x`
- are histogrammed along the first dimension and values in `y` are
- histogrammed along the second dimension.
- xedges : ndarray, shape(nx+1,)
- The bin edges along the first dimension.
- yedges : ndarray, shape(ny+1,)
- The bin edges along the second dimension.
- See Also
- --------
- histogram : 1D histogram
- histogramdd : Multidimensional histogram
- Notes
- -----
- When `normed` is True, then the returned histogram is the sample
- density, defined such that the sum over bins of the product
- ``bin_value * bin_area`` is 1.
- Please note that the histogram does not follow the Cartesian convention
- where `x` values are on the abscissa and `y` values on the ordinate
- axis. Rather, `x` is histogrammed along the first dimension of the
- array (vertical), and `y` along the second dimension of the array
- (horizontal). This ensures compatibility with `histogramdd`.
- Examples
- --------
- >>> from matplotlib.image import NonUniformImage
- >>> import matplotlib.pyplot as plt
- Construct a 2-D histogram with variable bin width. First define the bin
- edges:
- >>> xedges = [0, 1, 3, 5]
- >>> yedges = [0, 2, 3, 4, 6]
- Next we create a histogram H with random bin content:
- >>> x = np.random.normal(2, 1, 100)
- >>> y = np.random.normal(1, 1, 100)
- >>> H, xedges, yedges = np.histogram2d(x, y, bins=(xedges, yedges))
- >>> # Histogram does not follow Cartesian convention (see Notes),
- >>> # therefore transpose H for visualization purposes.
- >>> H = H.T
- :func:`imshow <matplotlib.pyplot.imshow>` can only display square bins:
- >>> fig = plt.figure(figsize=(7, 3))
- >>> ax = fig.add_subplot(131, title='imshow: square bins')
- >>> plt.imshow(H, interpolation='nearest', origin='lower',
- ... extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]])
- <matplotlib.image.AxesImage object at 0x...>
- :func:`pcolormesh <matplotlib.pyplot.pcolormesh>` can display actual edges:
- >>> ax = fig.add_subplot(132, title='pcolormesh: actual edges',
- ... aspect='equal')
- >>> X, Y = np.meshgrid(xedges, yedges)
- >>> ax.pcolormesh(X, Y, H)
- <matplotlib.collections.QuadMesh object at 0x...>
- :class:`NonUniformImage <matplotlib.image.NonUniformImage>` can be used to
- display actual bin edges with interpolation:
- >>> ax = fig.add_subplot(133, title='NonUniformImage: interpolated',
- ... aspect='equal', xlim=xedges[[0, -1]], ylim=yedges[[0, -1]])
- >>> im = NonUniformImage(ax, interpolation='bilinear')
- >>> xcenters = (xedges[:-1] + xedges[1:]) / 2
- >>> ycenters = (yedges[:-1] + yedges[1:]) / 2
- >>> im.set_data(xcenters, ycenters, H)
- >>> ax.images.append(im)
- >>> plt.show()
- """
- from numpy import histogramdd
- try:
- N = len(bins)
- except TypeError:
- N = 1
- if N != 1 and N != 2:
- xedges = yedges = asarray(bins)
- bins = [xedges, yedges]
- hist, edges = histogramdd([x, y], bins, range, normed, weights, density)
- return hist, edges[0], edges[1]
- @set_module('numpy')
- def mask_indices(n, mask_func, k=0):
- """
- Return the indices to access (n, n) arrays, given a masking function.
- Assume `mask_func` is a function that, for a square array a of size
- ``(n, n)`` with a possible offset argument `k`, when called as
- ``mask_func(a, k)`` returns a new array with zeros in certain locations
- (functions like `triu` or `tril` do precisely this). Then this function
- returns the indices where the non-zero values would be located.
- Parameters
- ----------
- n : int
- The returned indices will be valid to access arrays of shape (n, n).
- mask_func : callable
- A function whose call signature is similar to that of `triu`, `tril`.
- That is, ``mask_func(x, k)`` returns a boolean array, shaped like `x`.
- `k` is an optional argument to the function.
- k : scalar
- An optional argument which is passed through to `mask_func`. Functions
- like `triu`, `tril` take a second argument that is interpreted as an
- offset.
- Returns
- -------
- indices : tuple of arrays.
- The `n` arrays of indices corresponding to the locations where
- ``mask_func(np.ones((n, n)), k)`` is True.
- See Also
- --------
- triu, tril, triu_indices, tril_indices
- Notes
- -----
- .. versionadded:: 1.4.0
- Examples
- --------
- These are the indices that would allow you to access the upper triangular
- part of any 3x3 array:
- >>> iu = np.mask_indices(3, np.triu)
- For example, if `a` is a 3x3 array:
- >>> a = np.arange(9).reshape(3, 3)
- >>> a
- array([[0, 1, 2],
- [3, 4, 5],
- [6, 7, 8]])
- >>> a[iu]
- array([0, 1, 2, 4, 5, 8])
- An offset can be passed also to the masking function. This gets us the
- indices starting on the first diagonal right of the main one:
- >>> iu1 = np.mask_indices(3, np.triu, 1)
- with which we now extract only three elements:
- >>> a[iu1]
- array([1, 2, 5])
- """
- m = ones((n, n), int)
- a = mask_func(m, k)
- return nonzero(a != 0)
- @set_module('numpy')
- def tril_indices(n, k=0, m=None):
- """
- Return the indices for the lower-triangle of an (n, m) array.
- Parameters
- ----------
- n : int
- The row dimension of the arrays for which the returned
- indices will be valid.
- k : int, optional
- Diagonal offset (see `tril` for details).
- m : int, optional
- .. versionadded:: 1.9.0
- The column dimension of the arrays for which the returned
- arrays will be valid.
- By default `m` is taken equal to `n`.
- Returns
- -------
- inds : tuple of arrays
- The indices for the triangle. The returned tuple contains two arrays,
- each with the indices along one dimension of the array.
- See also
- --------
- triu_indices : similar function, for upper-triangular.
- mask_indices : generic function accepting an arbitrary mask function.
- tril, triu
- Notes
- -----
- .. versionadded:: 1.4.0
- Examples
- --------
- Compute two different sets of indices to access 4x4 arrays, one for the
- lower triangular part starting at the main diagonal, and one starting two
- diagonals further right:
- >>> il1 = np.tril_indices(4)
- >>> il2 = np.tril_indices(4, 2)
- Here is how they can be used with a sample array:
- >>> a = np.arange(16).reshape(4, 4)
- >>> a
- array([[ 0, 1, 2, 3],
- [ 4, 5, 6, 7],
- [ 8, 9, 10, 11],
- [12, 13, 14, 15]])
- Both for indexing:
- >>> a[il1]
- array([ 0, 4, 5, ..., 13, 14, 15])
- And for assigning values:
- >>> a[il1] = -1
- >>> a
- array([[-1, 1, 2, 3],
- [-1, -1, 6, 7],
- [-1, -1, -1, 11],
- [-1, -1, -1, -1]])
- These cover almost the whole array (two diagonals right of the main one):
- >>> a[il2] = -10
- >>> a
- array([[-10, -10, -10, 3],
- [-10, -10, -10, -10],
- [-10, -10, -10, -10],
- [-10, -10, -10, -10]])
- """
- tri_ = tri(n, m, k=k, dtype=bool)
- return tuple(broadcast_to(inds, tri_.shape)[tri_]
- for inds in indices(tri_.shape, sparse=True))
- def _trilu_indices_form_dispatcher(arr, k=None):
- return (arr,)
- @array_function_dispatch(_trilu_indices_form_dispatcher)
- def tril_indices_from(arr, k=0):
- """
- Return the indices for the lower-triangle of arr.
- See `tril_indices` for full details.
- Parameters
- ----------
- arr : array_like
- The indices will be valid for square arrays whose dimensions are
- the same as arr.
- k : int, optional
- Diagonal offset (see `tril` for details).
- See Also
- --------
- tril_indices, tril
- Notes
- -----
- .. versionadded:: 1.4.0
- """
- if arr.ndim != 2:
- raise ValueError("input array must be 2-d")
- return tril_indices(arr.shape[-2], k=k, m=arr.shape[-1])
- @set_module('numpy')
- def triu_indices(n, k=0, m=None):
- """
- Return the indices for the upper-triangle of an (n, m) array.
- Parameters
- ----------
- n : int
- The size of the arrays for which the returned indices will
- be valid.
- k : int, optional
- Diagonal offset (see `triu` for details).
- m : int, optional
- .. versionadded:: 1.9.0
- The column dimension of the arrays for which the returned
- arrays will be valid.
- By default `m` is taken equal to `n`.
- Returns
- -------
- inds : tuple, shape(2) of ndarrays, shape(`n`)
- The indices for the triangle. The returned tuple contains two arrays,
- each with the indices along one dimension of the array. Can be used
- to slice a ndarray of shape(`n`, `n`).
- See also
- --------
- tril_indices : similar function, for lower-triangular.
- mask_indices : generic function accepting an arbitrary mask function.
- triu, tril
- Notes
- -----
- .. versionadded:: 1.4.0
- Examples
- --------
- Compute two different sets of indices to access 4x4 arrays, one for the
- upper triangular part starting at the main diagonal, and one starting two
- diagonals further right:
- >>> iu1 = np.triu_indices(4)
- >>> iu2 = np.triu_indices(4, 2)
- Here is how they can be used with a sample array:
- >>> a = np.arange(16).reshape(4, 4)
- >>> a
- array([[ 0, 1, 2, 3],
- [ 4, 5, 6, 7],
- [ 8, 9, 10, 11],
- [12, 13, 14, 15]])
- Both for indexing:
- >>> a[iu1]
- array([ 0, 1, 2, ..., 10, 11, 15])
- And for assigning values:
- >>> a[iu1] = -1
- >>> a
- array([[-1, -1, -1, -1],
- [ 4, -1, -1, -1],
- [ 8, 9, -1, -1],
- [12, 13, 14, -1]])
- These cover only a small part of the whole array (two diagonals right
- of the main one):
- >>> a[iu2] = -10
- >>> a
- array([[ -1, -1, -10, -10],
- [ 4, -1, -1, -10],
- [ 8, 9, -1, -1],
- [ 12, 13, 14, -1]])
- """
- tri_ = ~tri(n, m, k=k - 1, dtype=bool)
- return tuple(broadcast_to(inds, tri_.shape)[tri_]
- for inds in indices(tri_.shape, sparse=True))
- @array_function_dispatch(_trilu_indices_form_dispatcher)
- def triu_indices_from(arr, k=0):
- """
- Return the indices for the upper-triangle of arr.
- See `triu_indices` for full details.
- Parameters
- ----------
- arr : ndarray, shape(N, N)
- The indices will be valid for square arrays.
- k : int, optional
- Diagonal offset (see `triu` for details).
- Returns
- -------
- triu_indices_from : tuple, shape(2) of ndarray, shape(N)
- Indices for the upper-triangle of `arr`.
- See Also
- --------
- triu_indices, triu
- Notes
- -----
- .. versionadded:: 1.4.0
- """
- if arr.ndim != 2:
- raise ValueError("input array must be 2-d")
- return triu_indices(arr.shape[-2], k=k, m=arr.shape[-1])
|